<!DOCTYPE html>


  <html class="dark page-post">


<head><meta name="generator" content="Hexo 3.9.0">
  <meta charset="utf-8">
  
  <title>Electron构建跨平台应用mac/windows/linux | Poetry&#39;s Blog</title>

  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

  
    <meta name="keywords" content="Electron,Node,">
  

  <meta name="description" content="一、前言 NW.js 和 Electron 都可以用前端的知识来开发桌面应用。NW.js 和 Electron起初是同一 个作者开发。后来种种原因分为两个产品。一个命名为 NW.js(英特尔公司提供技术支持)、 另一命名为 Electron(Github 公司提供技术支持)。 NW.js 和 Electron 可以用 Nodejs 中几乎所有的模块。NW.js 和 Electron不仅可以把 ht">
<meta name="keywords" content="Electron,Node">
<meta property="og:type" content="article">
<meta property="og:title" content="Electron构建跨平台应用mac&#x2F;windows&#x2F;linux">
<meta property="og:url" content="http://blog.poetries.top/2019/01/06/electron-summary/index.html">
<meta property="og:site_name" content="Poetry&#39;s Blog">
<meta property="og:description" content="一、前言 NW.js 和 Electron 都可以用前端的知识来开发桌面应用。NW.js 和 Electron起初是同一 个作者开发。后来种种原因分为两个产品。一个命名为 NW.js(英特尔公司提供技术支持)、 另一命名为 Electron(Github 公司提供技术支持)。 NW.js 和 Electron 可以用 Nodejs 中几乎所有的模块。NW.js 和 Electron不仅可以把 ht">
<meta property="og:locale" content="zh-Hans">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/48.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/49.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/50.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/51.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/52.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/53.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/54.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/55.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/56.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/57.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/58.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/59.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/60.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/61.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/62.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/63.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/64.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/65.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/66.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/67.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/68.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/69.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/70.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/71.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/72.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/73.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/74.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/75.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/76.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/77.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/78.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/79.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/80.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/81.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/82.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/83.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/20191001/84.png">
<meta property="og:updated_time" content="2020-08-15T04:25:31.906Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Electron构建跨平台应用mac&#x2F;windows&#x2F;linux">
<meta name="twitter:description" content="一、前言 NW.js 和 Electron 都可以用前端的知识来开发桌面应用。NW.js 和 Electron起初是同一 个作者开发。后来种种原因分为两个产品。一个命名为 NW.js(英特尔公司提供技术支持)、 另一命名为 Electron(Github 公司提供技术支持)。 NW.js 和 Electron 可以用 Nodejs 中几乎所有的模块。NW.js 和 Electron不仅可以把 ht">
<meta name="twitter:image" content="https://poetries1.gitee.io/img-repo/20191001/48.png">

  

  
    <link rel="icon" href="/favicon.ico">
  

  <link href="/css/styles.css?v=c114cbeddx" rel="stylesheet">
<link href="/css/other.css?v=c114cbeddx" rel="stylesheet">


  
    <link rel="stylesheet" href="/css/personal-style.css">
  

  

  
  <script type="text/javascript">
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "//hm.baidu.com/hm.js?40b1f89aa80f2527b3db779c6898c879";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>


  
  <script type="text/javascript">
	(function(){
	    var bp = document.createElement('script');
	    var curProtocol = window.location.protocol.split(':')[0];
	    if (curProtocol === 'https') {
	        bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';        
	    }
	    else {
	        bp.src = 'http://push.zhanzhang.baidu.com/push.js';
	    }
	    var s = document.getElementsByTagName("script")[0];
	    s.parentNode.insertBefore(bp, s);
	})();
  </script>



  
    <script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
    <link rel="stylesheet" href="//cdn.bootcss.com/font-awesome/4.3.0/css/font-awesome.min.css">
  

  <!-- 聊天系统 -->
  
    
   <link type="text/css" rel="stylesheet" href="/renxi/default.css">
   <style>
      #modal {
        position: static !important;
      }
      .filter {
        width: 100%;
        height: 100%;
        position: absolute;
        top: 0;
        left: 0;
        background: #fe5757;
        animation: colorChange 30s ease-in-out infinite;
        animation-fill-mode: both;
        mix-blend-mode: overlay;
      }
  
      @keyframes colorChange {
        0%, 100% {
            opacity: 0;
        }
        50% {
            opacity: .9;
        }
      }
   </style>
</head>
</html>
<body>
  
  
    <span id="toolbox-mobile" class="toolbox-mobile">导航</span>
  

  <div class="post-header CENTER">
   
  <div class="toolbox">
    <a class="toolbox-entry" href="/">
      <span class="toolbox-entry-text">导航</span>
      <i class="icon-angle-down"></i>
      <i class="icon-home"></i>
    </a>
    <ul class="list-toolbox">
      
        <li class="item-toolbox">
          <a
            class="CIRCLE"
            href="/archives/"
            rel="noopener noreferrer"
            target="_self"
            >
            博客
          </a>
        </li>
      
        <li class="item-toolbox">
          <a
            class="CIRCLE"
            href="/categories/"
            rel="noopener noreferrer"
            target="_self"
            >
            分类
          </a>
        </li>
      
        <li class="item-toolbox">
          <a
            class="CIRCLE"
            href="/tags/"
            rel="noopener noreferrer"
            target="_self"
            >
            标签
          </a>
        </li>
      
        <li class="item-toolbox">
          <a
            class="CIRCLE"
            href="/search/"
            rel="noopener noreferrer"
            target="_self"
            >
            搜索
          </a>
        </li>
      
        <li class="item-toolbox">
          <a
            class="CIRCLE"
            href="/link/"
            rel="noopener noreferrer"
            target="_self"
            >
            友链
          </a>
        </li>
      
        <li class="item-toolbox">
          <a
            class="CIRCLE"
            href="/about/"
            rel="noopener noreferrer"
            target="_self"
            >
            关于
          </a>
        </li>
      
    </ul>
  </div>


</div>


  <div id="toc" class="toc-article">
    <strong class="toc-title">文章目录<i class="iconfont toc-title" style="display:inline-block;color:#87998d;width:20px;height:20px;">&#xf004b;</i></strong>
    <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#一、前言"><span class="toc-text">一、前言</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#二、环境搭建"><span class="toc-text">二、环境搭建</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#三、Electron-运行流程"><span class="toc-text">三、Electron 运行流程</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#3-1-Electron-运行的流程"><span class="toc-text">3.1 Electron 运行的流程</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3-2-Electron-主进程和渲染进程"><span class="toc-text">3.2 Electron 主进程和渲染进程</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3-3-Electron-渲染进程中通过-Nodejs-读取本地文件"><span class="toc-text">3.3 Electron 渲染进程中通过 Nodejs 读取本地文件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3-4-Electron-开启调试模式"><span class="toc-text">3.4 Electron 开启调试模式</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#四、Electron-模块介绍"><span class="toc-text">四、Electron 模块介绍</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#4-1-Electron-主进程和渲染进程中的模块"><span class="toc-text">4.1 Electron 主进程和渲染进程中的模块</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#4-2-Electron-remote-模块"><span class="toc-text">4.2 Electron remote 模块</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#4-3-通过BrowserWindow-打开新窗口"><span class="toc-text">4.3 通过BrowserWindow 打开新窗口</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#五、自定义顶部菜单-右键菜单"><span class="toc-text">五、自定义顶部菜单/右键菜单</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#5-1-主进程中调用Menu模块-自定义软件顶部菜单"><span class="toc-text">5.1 主进程中调用Menu模块-自定义软件顶部菜单</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-2-渲染进程中调用Menu模块"><span class="toc-text">5.2 渲染进程中调用Menu模块</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-3-渲染进程中自定义右键菜单"><span class="toc-text">5.3 渲染进程中自定义右键菜单</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#六、进程通信"><span class="toc-text">六、进程通信</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#6-1-主进程与渲染进程之间的通信"><span class="toc-text">6.1 主进程与渲染进程之间的通信</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#6-1-1-渲染进程给主进程发送异步消息"><span class="toc-text">6.1.1 渲染进程给主进程发送异步消息</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#6-1-2-渲染进程发送消息，主进程接收消息并反馈"><span class="toc-text">6.1.2 渲染进程发送消息，主进程接收消息并反馈</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#6-1-3-渲染进程给主进程发送同步消息"><span class="toc-text">6.1.3 渲染进程给主进程发送同步消息</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#6-1-4-渲染进程广播通知主进程打开窗口"><span class="toc-text">6.1.4 渲染进程广播通知主进程打开窗口</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#6-2-渲染进程与渲染进程之间的通信"><span class="toc-text">6.2 渲染进程与渲染进程之间的通信</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#6-2-1-localstorage传值"><span class="toc-text">6.2.1 localstorage传值</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#6-2-2-BrowserWindow和webContents方式实现"><span class="toc-text">6.2.2 BrowserWindow和webContents方式实现</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#七、Electron-Shell-模块"><span class="toc-text">七、Electron Shell 模块</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#7-1-Shell-模块使用"><span class="toc-text">7.1 Shell 模块使用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#7-2-Electron-DOM-lt-webview-gt-标签"><span class="toc-text">7.2 Electron DOM &lt;webview&gt; 标签</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#7-3-shell模块-lt-webview-gt-结合Menu模块使用案例"><span class="toc-text">7.3 shell模块&lt;webview&gt;结合Menu模块使用案例</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#八、Electron-dialog-弹出框"><span class="toc-text">八、Electron dialog 弹出框</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#九、实现一个类似EditPlus的简易记事本代码编辑器"><span class="toc-text">九、实现一个类似EditPlus的简易记事本代码编辑器</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#十、系统托盘、托盘右键菜单、托盘图标闪烁"><span class="toc-text">十、系统托盘、托盘右键菜单、托盘图标闪烁</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#十一、消息通知、监听网络变-化、网络变化弹出通知框"><span class="toc-text">十一、消息通知、监听网络变 化、网络变化弹出通知框</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#11-1-消息通知"><span class="toc-text">11.1 消息通知</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#11-2-监听网络变化"><span class="toc-text">11.2 监听网络变化</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#十二、注册全局快捷键-剪切板事件-nativeImage-模块"><span class="toc-text">十二、注册全局快捷键/剪切板事件/nativeImage 模块</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#12-1-注册全局快捷键"><span class="toc-text">12.1 注册全局快捷键</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#12-2-剪切板clipboard、nativeImage-模块"><span class="toc-text">12.2  剪切板clipboard、nativeImage 模块</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#十三、结合electron-vue"><span class="toc-text">十三、结合electron-vue</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#13-1-electron-vue-的使用"><span class="toc-text">13.1 electron-vue 的使用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#13-2-electron-vue-中使用-sass-ElementUi"><span class="toc-text">13.2 electron-vue 中使用 sass/ElementUi</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#13-3-electron-vue-中隐藏顶部菜单隐藏"><span class="toc-text">13.3 electron-vue 中隐藏顶部菜单隐藏</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#13-4-使用electron-vue开发舆情监控系统"><span class="toc-text">13.4 使用electron-vue开发舆情监控系统</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#13-4-1-配置开发环境"><span class="toc-text">13.4.1 配置开发环境</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#13-4-2-主进程配置"><span class="toc-text">13.4.2 主进程配置</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#13-4-3-渲染进程配置"><span class="toc-text">13.4.3 渲染进程配置</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#13-4-4-多平台打包"><span class="toc-text">13.4.4 多平台打包</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#13-4-4-1-打包介绍"><span class="toc-text">13.4.4.1 打包介绍</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#13-4-4-2-修改应用信息"><span class="toc-text">13.4.4.2 修改应用信息</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#13-4-4-3-打包遇到的问题"><span class="toc-text">13.4.4.3 打包遇到的问题</span></a></li></ol></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#十四、更多参考"><span class="toc-text">十四、更多参考</span></a></li></ol>
  </div>
  




<div class="content content-post CENTER">
   <!-- canvas 彩带 -->
<canvas id="evanyou" width="1302" height="678" style="position: fixed;width: 100%;height: 100%;top: 0;left:0;z-index:-1;"></canvas>

<article id="post-electron-summary" class="article article-type-post" itemprop="blogPost">
  <header class="article-header" style="position:relative;">
    <h1 class="post-title">Electron构建跨平台应用mac/windows/linux</h1>

    <div class="article-meta">
      <span>
        <i class="icon-calendar"></i>
        <span>2019.01.06</span>
      </span>

      
        <span class="article-author">
          <i class="icon-user"></i>
          <span>Poetry</span>
        </span>
      

      
  <span class="article-category">
    <i class="icon-list"></i>
    <a class="article-category-link" href="/categories/Front-End/">Front-End</a>
  </span>



      

      
      <i class="fa fa-eye"></i> 
        <span id="busuanzi_container_page_pv">
           &nbsp热度 <span id="busuanzi_value_page_pv">
           <i class="fa fa-spinner fa-spin"></i></span>℃
        </span>
      
      
       
          <span class="post-count">
            <i class="fa fa-file-word-o"></i>&nbsp
            <span>字数统计 9.8k字</span>
          </span>

          <span class="post-count">
            <i class="fa fa-columns"></i>&nbsp
            <span>阅读时长 44分</span>
          </span>
      
      
    </div>

    <i class="iconfont" id="toc-eye" style="display:inline-block;color:#b36619;position:absolute;top:0;right:0;cursor:pointer;
    font-size: 24px;">&#xe61c;</i>

  </header>

  <div class="article-content">
    
      <div id="container">
        <h1 id="一、前言"><a href="#一、前言" class="headerlink" title="一、前言"></a>一、前言</h1><ul>
<li><code>NW.js</code> 和 <code>Electron</code> 都可以用前端的知识来开发桌面应用。<code>NW.js</code> 和 <code>Electron</code>起初是同一 个作者开发。后来种种原因分为两个产品。一个命名为 <code>NW.js</code>(英特尔公司提供技术支持)、 另一命名为 <code>Electron</code>(Github 公司提供技术支持)。</li>
<li><code>NW.js</code> 和 <code>Electron</code> 可以用 <code>Nodejs</code> 中几乎所有的模块。<code>NW.js</code> 和 <code>Electron</code>不仅可以把 <code>html</code> 写的 <code>web</code> 页面打包成跨平台可以安装到电脑上面的软件，也可以通过 <code>javascript</code> 访问操作 系统原生的 <code>UI</code> 和 <code>Api</code>(控制窗口、添加菜单项目、托盘应用菜单、读写文件、访问剪贴板)。</li>
</ul>
<blockquote>
<p> <code>github</code> 的 <code>atom</code> 编辑器、微软的 <code>vscode</code> 编辑器，包括阿里内部的一些 软件也是用 <code>electron</code> 开发的</p>
</blockquote>
<p><strong>1. Electron 是由谁开发的?</strong></p>
<blockquote>
<p><code>Electron</code> 是由 <code>Github</code> 开发</p>
</blockquote>
<p><strong>2.  Electron 是什么?</strong></p>
<blockquote>
<p><code>Electron</code> 是一个用 <code>HTML</code>，<code>CSS</code> 和 <code>JavaScript</code> 来构建跨平台桌面应用程序的一个开源库</p>
</blockquote>
<p><strong>3. Electron 把 HTML，CSS 和 JavaScript 组合的程序构建为跨平台桌面应用程序的原理 是什么?</strong></p>
<blockquote>
<p>原理为 <code>Electron</code> 通过将 <code>Chromium</code> 和 <code>Node.js</code> 合并到同一个运行时环境中，并将其打包为 <code>Mac</code>，<code>Windows</code> 和 <code>Linux</code> 系统下的应用来实现这一目的。</p>
</blockquote>
<p><strong>4. Electron 何时出现的，为什么会出现?</strong></p>
<blockquote>
<p><code>Electron</code> 于 <code>2013</code> 年作为构建 <code>Atom</code> 的框架而被开发出来。这两个项目在 <code>2014</code> 春季开源。 (Atom:为 Github 上可编程的文本编辑器)</p>
</blockquote>
<p><strong>一些历史:</strong></p>
<ul>
<li><code>2013</code> 年 <code>4</code> 月 <code>Atom Shell</code> 项目启动 。</li>
<li><code>2014</code> 年 <code>5</code> 月 <code>Atom Shell</code> 被开源 。</li>
<li><code>2015</code> 年 <code>4</code> 月 <code>Atom Shell</code> 被重命名为 <code>Electron</code> </li>
<li><code>2016</code> 年 <code>5</code> 月 <code>Electron</code> 发布了 <code>v1.0.0</code> 版本 </li>
</ul>
<p><strong>5. Electron 当前流行程度?</strong></p>
<blockquote>
<p>目前 <code>Electron</code> 已成为开源开发者、初创企业和老牌公司常用的开发工具。</p>
</blockquote>
<p><strong>6. Electron 当前由那些人在维护支持?</strong></p>
<blockquote>
<p><code>Electron</code> 当前由 <code>Github</code> 上的一支团队和一群活跃的贡献者维护。有些贡献者是独立开发者，有些则在用 <code>Electron</code> 构建应用的大型公司里工作。</p>
</blockquote>
<p><strong>7. Electron 新版本多久发布一次?</strong></p>
<blockquote>
<p><code>Electron</code> 的版本发布相当频繁。每当 <code>Chromium</code>、<code>Node.js</code> 有重要的 <code>bug</code> 修复，新 <code>API</code> 或是版本更新时 <code>Electron</code> 会发布新版本。</p>
</blockquote>
<ul>
<li>一般 <code>Chromium</code> 发行新的稳定版后的一到两周之内，<code>Electron</code> 中 <code>Chromium</code> 的版本会对其进行更新，具体时间根据升级所需的工作量而定。<br>一般 <code>Node.js</code> 发行新的稳定版一个月后，<code>Electron</code> 中 <code>Node.js</code> 的版本会对其进行更新，具 体时间根据升级所需的工作量而定。</li>
</ul>
<p><strong>8. Electron 的核心理念是什么?</strong></p>
<blockquote>
<p><code>Electron</code> 的核心理念是:保持 <code>Electron</code> 的体积小和可持续性开发。<br>如:为了保持 <code>Electron</code> 的小巧 (文件体积) 和可持续性开发 (以防依赖库和 <code>API</code> 的泛滥) ， <code>Electron</code> 限制了所使用的核心项目的数量。<br>比如 <code>Electron</code> 只用了 <code>Chromium</code> 的渲染库而不是其全部组件。这使得升级 <code>Chromium</code> 更加容易，但也意味着 <code>Electron</code> 缺少了 <code>Google Chrome</code> 里的一些浏览器相关的特性。 添加到 <code>Electron</code> 的新功能应该主要是原生 <code>API</code>。 如果可以的话，一个功能应该尽可能的成 为一个 <code>Node.js</code> 模块。</p>
</blockquote>
<p><strong>9. Electron 当前的最新版本为多少?</strong></p>
<blockquote>
<p><code>Electron</code> 当前的最新版本为 <code>4.0.1</code> (当前时间为 <code>2019</code> 年 <code>1</code> 月 <code>6</code> 号)</p>
</blockquote>
<h1 id="二、环境搭建"><a href="#二、环境搭建" class="headerlink" title="二、环境搭建"></a>二、环境搭建</h1><p><strong>1. 安装 electron</strong></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install -g electron</span><br></pre></td></tr></table></figure>
<p><strong>2. 克隆一个仓库、快速启动一个项目</strong></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 克隆示例项目的仓库</span></span><br><span class="line">git <span class="built_in">clone</span> https://github.com/electron/electron-quick-start</span><br><span class="line"></span><br><span class="line"><span class="comment"># 进入这个仓库</span></span><br><span class="line"><span class="built_in">cd</span> electron-quick-start</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装依赖并运行</span></span><br><span class="line">npm install &amp;&amp; npm start</span><br></pre></td></tr></table></figure>
<p><strong>3. 手动搭建一个 electron 项目</strong></p>
<ol>
<li>新建一个项目目录 例如: <code>electrondemo01</code></li>
<li>在 <code>electrondemo01</code> 目录下面新建三个文件: <code>index.html</code>、<code>main.js</code> 、<code>package.json</code></li>
<li><code>index.html</code> 里面用 <code>css</code> 进行布局(以前怎么写现在还是怎么写)</li>
<li>在 <code>main.js</code> 中写如下代码</li>
</ol>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> electron =<span class="built_in">require</span>(<span class="string">'electron'</span>); <span class="comment">//electron 对象的引用</span></span><br><span class="line"><span class="keyword">const</span> app=electron.app; <span class="comment">//BrowserWindow 类的引用</span></span><br><span class="line"><span class="keyword">const</span> BrowserWindow=electron.BrowserWindow;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> mainWindow=<span class="literal">null</span>; <span class="comment">//监听应用准备完成的事件 app.on('ready',function()&#123;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//监听应用准备完成的事件</span></span><br><span class="line">app.on(<span class="string">'ready'</span>,<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="comment">//创建窗口</span></span><br><span class="line">    mainWindow=<span class="keyword">new</span> BrowserWindow(&#123;<span class="attr">width</span>: <span class="number">800</span>, <span class="attr">height</span>: <span class="number">600</span>&#125;); mainWindow.loadFile(<span class="string">'index.html'</span>);</span><br><span class="line">    </span><br><span class="line">    mainWindow.on(<span class="string">'closed'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">        mainWindow = <span class="literal">null</span>; &#125;)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">//监听所有窗口关闭的事件 </span></span><br><span class="line">app.on(<span class="string">'window-all-closed'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// On OS X it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q </span></span><br><span class="line">    <span class="keyword">if</span> (process.platform !== <span class="string">'darwin'</span>) &#123;</span><br><span class="line">        app.quit(); </span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol start="5">
<li>运行</li>
</ol>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">electron . <span class="comment">#注意:命令后面有个点</span></span><br></pre></td></tr></table></figure>
<p><strong>4. electron-forge 搭建一个 electron 项目</strong></p>
<blockquote>
<p><code>electron-forge</code> 相当于 <code>electron</code> 的一个脚手架，可以让我们更方便的创建、运行、打包 <code>electron</code> 项目</p>
</blockquote>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install -g electron-forge </span><br><span class="line"></span><br><span class="line">electron-forge init my-new-app </span><br><span class="line"></span><br><span class="line"><span class="built_in">cd</span> my-new-app</span><br><span class="line"></span><br><span class="line">npm start</span><br></pre></td></tr></table></figure>
<h1 id="三、Electron-运行流程"><a href="#三、Electron-运行流程" class="headerlink" title="三、Electron 运行流程"></a>三、Electron 运行流程</h1><h2 id="3-1-Electron-运行的流程"><a href="#3-1-Electron-运行的流程" class="headerlink" title="3.1 Electron 运行的流程"></a>3.1 Electron 运行的流程</h2><p> <img src="https://poetries1.gitee.io/img-repo/20191001/48.png" alt></p>
<h2 id="3-2-Electron-主进程和渲染进程"><a href="#3-2-Electron-主进程和渲染进程" class="headerlink" title="3.2 Electron 主进程和渲染进程"></a>3.2 Electron 主进程和渲染进程</h2><ul>
<li><code>Electron</code> 运行 <code>package.json</code> 的 <code>main</code> 脚本的进程被称为主进程。 </li>
<li>在主进程中运行的脚本通过创建 <code>web</code> 页面来展示用户界面。 一个 <code>Electron</code> 应用总是有且只有一个主进程。</li>
<li>由于 <code>Electron</code> 使用了 <code>Chromium</code>(谷歌浏览器)来展示 <code>web</code> 页面，所以 <code>Chromium</code> 的 多进程架构也被使用到。 每个 <code>Electron</code> 中的 <code>web</code> 页面运行在它自己的渲染进程中。</li>
<li><p>主进程使用 <code>BrowserWindow</code> 实例创建页面。每个 <code>BrowserWindow</code> 实例都在自己的渲 染进程里运行页面。 当一个 <code>BrowserWindow</code>实例被销毁后，相应的渲染进程也会被终止</p>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/49.png" alt></p>
</li>
</ul>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/50.png" alt></p>
<ul>
<li>进程:进程是计算机中的程序关于某数据集合上的一次运行活动，是 系统进行资源分配和调度的基本单位，是操作系统结构的基础。</li>
<li>线程:在一个程序里的一个执行路线就叫做线程(<code>thread</code>)。更准确的定义是: 线程是“一个进程内部的控制序列”。</li>
<li>线程和进程:一个程序至少有一个进程,一个进程至少有一个线程</li>
</ul>
<h2 id="3-3-Electron-渲染进程中通过-Nodejs-读取本地文件"><a href="#3-3-Electron-渲染进程中通过-Nodejs-读取本地文件" class="headerlink" title="3.3 Electron 渲染进程中通过 Nodejs 读取本地文件"></a>3.3 Electron 渲染进程中通过 Nodejs 读取本地文件</h2><blockquote>
<p>在普通的浏览器中，<code>web</code>页面通常在一个沙盒环境中运行，不被允许去接触原生的资源。 然而 <code>Electron</code> 的用户在 <code>Node.js</code> 的 <code>API</code>支持下可以在页面中和操作系统进行一些底层交 互。<br><code>Nodejs</code> 在主进程和渲染进程中都可以使用。渲染进程因为安全限制，不能直接操作生 <code>GUI</code>。虽然如此，因为集成了 Nodejs，渲染进程也有了操作系统底层 <code>API</code>的能力，<code>Nodejs</code> 中常用的 <code>Path</code>、<code>fs</code>、<code>Crypto</code> 等模块在 <code>Electron</code> 可以直接使用，方便我们处理链接、路径、 文件 <code>MD5</code> 等，同时 <code>npm</code> 还有成千上万的模块供我们选择。</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> fs = <span class="built_in">require</span>(<span class="string">'fs'</span>);</span><br><span class="line"><span class="keyword">var</span> content = <span class="built_in">document</span>.getElementById(<span class="string">'content'</span>); </span><br><span class="line"><span class="keyword">var</span> button = <span class="built_in">document</span>.getElementById(<span class="string">'button'</span>);</span><br><span class="line"></span><br><span class="line">button.addEventListener(<span class="string">'click'</span>,<span class="function"><span class="keyword">function</span>(<span class="params">e</span>)</span>&#123;</span><br><span class="line">    fs.readFile(<span class="string">'package.json'</span>,<span class="string">'utf8'</span>,<span class="function"><span class="keyword">function</span>(<span class="params">err,data</span>)</span>&#123; </span><br><span class="line">        content.textContent = data;</span><br><span class="line">        <span class="built_in">console</span>.log(data);</span><br><span class="line">    &#125;); </span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<h2 id="3-4-Electron-开启调试模式"><a href="#3-4-Electron-开启调试模式" class="headerlink" title="3.4 Electron 开启调试模式"></a>3.4 Electron 开启调试模式</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line">mainWindow.webContents.openDevTools();</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/51.png" alt></p>
<h1 id="四、Electron-模块介绍"><a href="#四、Electron-模块介绍" class="headerlink" title="四、Electron 模块介绍"></a>四、Electron 模块介绍</h1><blockquote>
<p><code>Electron</code> 模块介绍、<code>remote</code> 模块、通 过 <code>BrowserWindow</code> 打开新窗口</p>
</blockquote>
<h2 id="4-1-Electron-主进程和渲染进程中的模块"><a href="#4-1-Electron-主进程和渲染进程中的模块" class="headerlink" title="4.1 Electron 主进程和渲染进程中的模块"></a>4.1 Electron 主进程和渲染进程中的模块</h2><p><img src="https://poetries1.gitee.io/img-repo/20191001/52.png" alt></p>
<h2 id="4-2-Electron-remote-模块"><a href="#4-2-Electron-remote-模块" class="headerlink" title="4.2 Electron remote 模块"></a>4.2 Electron remote 模块</h2><blockquote>
<p><code>remote</code> 模块提供了一种在渲染进程(网页)和主进程之间进行进程间通讯(<code>IPC</code>)的简便途径</p>
</blockquote>
<blockquote>
<p><code>Electron</code> 中, 与 <code>GUI</code> 相关的模块(如 <code>dialog</code>, <code>menu</code> 等)只存在于主进程，而不在渲染进程中 。为了能从渲染进程中使用它们，需要用<code>ipc</code>模块来给主进程发送进程间消息。使用 <code>remote</code> 模块，可以调用主进程对象的方法，而无需显式地发送进程间消息，这类似于 <code>Java</code> 的 <code>RMI</code></p>
</blockquote>
<h2 id="4-3-通过BrowserWindow-打开新窗口"><a href="#4-3-通过BrowserWindow-打开新窗口" class="headerlink" title="4.3 通过BrowserWindow 打开新窗口"></a>4.3 通过BrowserWindow 打开新窗口</h2><blockquote>
<p><code>Electron</code> 渲染进程中通过 <strong><code>remote</code> 模块调用主进程中的 <code>BrowserWindow</code></strong> 打开新窗口</p>
</blockquote>
<blockquote>
<p><a href="https://electronjs.org/docs/api/browser-window" target="_blank" rel="noopener">https://electronjs.org/docs/api/browser-window</a></p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 主进程代码</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> electron = <span class="built_in">require</span>(<span class="string">'electron'</span>); </span><br><span class="line"></span><br><span class="line"><span class="comment">// 控制应用生命周期的模块 </span></span><br><span class="line"><span class="keyword">const</span> &#123;app&#125; = electron;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建本地浏览器窗口的模块 </span></span><br><span class="line"><span class="keyword">const</span> &#123;BrowserWindow&#125; = electron;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 指向窗口对象的一个全局引用，如果没有这个引用，那么当该 javascript 对象被垃圾回收 的</span></span><br><span class="line"><span class="comment">// 时候该窗口将会自动关闭</span></span><br><span class="line"><span class="keyword">let</span> win;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">createWindow</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 创建一个新的浏览器窗口</span></span><br><span class="line">    win = <span class="keyword">new</span> BrowserWindow(&#123;<span class="attr">width</span>: <span class="number">1104</span>, <span class="attr">height</span>: <span class="number">620</span>&#125;);<span class="comment">//570+50</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 并且装载应用的 index.html 页面</span></span><br><span class="line">    win.loadURL(<span class="string">`file://<span class="subst">$&#123;__dirname&#125;</span>/html/index.html`</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 打开开发工具页面</span></span><br><span class="line">    win.webContents.openDevTools();</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//当窗口关闭时调用的方法</span></span><br><span class="line">    win.on(<span class="string">'closed'</span>, () =&gt; &#123;</span><br><span class="line">        <span class="comment">// 解除窗口对象的引用，通常而言如果应用支持多个窗口的话，你会在一个数组里 // 存放窗口对象，在窗口关闭的时候应当删除相应的元素。</span></span><br><span class="line">        win = <span class="literal">null</span>;</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 当 Electron 完成初始化并且已经创建了浏览器窗口，则该方法将会被调用。</span></span><br><span class="line"><span class="comment">// 有些 API 只能在该事件发生后才能被使用</span></span><br><span class="line">app.on(<span class="string">'ready'</span>, createWindow);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 当所有的窗口被关闭后退出应用 </span></span><br><span class="line">app.on(<span class="string">'window-all-closed'</span>, () =&gt; &#123;</span><br><span class="line">    <span class="comment">// 对于 OS X 系统，应用和相应的菜单栏会一直激活直到用户通过 Cmd + Q 显式退出 </span></span><br><span class="line">    <span class="keyword">if</span> (process.platform !== <span class="string">'darwin'</span>) &#123;</span><br><span class="line">        app.quit(); </span><br><span class="line">    &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">app.on(<span class="string">'activate'</span>, () =&gt; &#123;</span><br><span class="line">    <span class="comment">// 对于 OS X 系统，当 dock 图标被点击后会重新创建一个 app 窗口，并且不会有其他</span></span><br><span class="line">    <span class="comment">// 窗口打开</span></span><br><span class="line">    <span class="keyword">if</span> (win === <span class="literal">null</span>) &#123;</span><br><span class="line">        createWindow(); </span><br><span class="line">    &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 在这个文件后面你可以直接包含你应用特定的由主进程运行的代码。 </span></span><br><span class="line"><span class="comment">// 也可以把这些代码放在另一个文件中然后在这里导入</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 渲染进程代码 /src/render/index.js</span></span><br><span class="line"><span class="comment">// 打开新窗口属性用法有点类似vscode打开新的窗口</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> btn = <span class="built_in">document</span>.querySelector(<span class="string">'#btn'</span>);</span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>);</span><br><span class="line"><span class="keyword">const</span> BrowerWindow = <span class="built_in">require</span>(<span class="string">'electron'</span>).remote.BrowserWindow;</span><br><span class="line"></span><br><span class="line">btn.onclick = <span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">    win = <span class="keyword">new</span> BrowerWindow(&#123; </span><br><span class="line">        width: <span class="number">300</span>,</span><br><span class="line">        height: <span class="number">200</span>, </span><br><span class="line">        frame: <span class="literal">false</span>, <span class="comment">// false隐藏关闭按钮、菜单选项 true显示</span></span><br><span class="line">        fullscreen:<span class="literal">true</span>, <span class="comment">// 全屏展示</span></span><br><span class="line">        transparent: <span class="literal">true</span> </span><br><span class="line">    &#125;) </span><br><span class="line"></span><br><span class="line">    win.loadURL(path.join(<span class="string">'file:'</span>,__dirname,<span class="string">'news.html'</span>));</span><br><span class="line"></span><br><span class="line">    win.on(<span class="string">'close'</span>,()=&gt;&#123;win = <span class="literal">null</span>&#125;);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/53.png" alt></p>
<h1 id="五、自定义顶部菜单-右键菜单"><a href="#五、自定义顶部菜单-右键菜单" class="headerlink" title="五、自定义顶部菜单/右键菜单"></a>五、自定义顶部菜单/右键菜单</h1><p><img src="https://poetries1.gitee.io/img-repo/20191001/54.png" alt></p>
<h2 id="5-1-主进程中调用Menu模块-自定义软件顶部菜单"><a href="#5-1-主进程中调用Menu模块-自定义软件顶部菜单" class="headerlink" title="5.1 主进程中调用Menu模块-自定义软件顶部菜单"></a>5.1 主进程中调用Menu模块-自定义软件顶部菜单</h2><blockquote>
<p><a href="https://electronjs.org/docs/api/menu-item" target="_blank" rel="noopener">https://electronjs.org/docs/api/menu-item</a></p>
</blockquote>
<blockquote>
<p><code>Electron</code> 中 <code>Menu</code> 模块可以用来创建原生菜单，它可用作应用菜单和 <code>context</code> 菜单</p>
</blockquote>
<blockquote>
<p>这个模块是一个主进程的模块，并且可以通过 <code>remote</code> 模块给渲染进程调用</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// main/menu.js</span></span><br><span class="line"><span class="keyword">const</span> &#123; Menu &#125;  = <span class="built_in">require</span>(<span class="string">'electron'</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 文档 https://electronjs.org/docs/api/menu-item</span></span><br><span class="line"><span class="comment">// 菜单项目</span></span><br><span class="line"><span class="keyword">let</span> menus = [</span><br><span class="line">    &#123;</span><br><span class="line">        label: <span class="string">'文件'</span>,</span><br><span class="line">        submenu: [</span><br><span class="line">            &#123;</span><br><span class="line">                label: <span class="string">'新建文件'</span>,</span><br><span class="line">                accelerator: <span class="string">'ctrl+n'</span>, <span class="comment">// 绑定快捷键</span></span><br><span class="line">                click: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123; <span class="comment">// 绑定事件</span></span><br><span class="line">                    <span class="built_in">console</span>.log(<span class="string">'新建文件'</span>)</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                label: <span class="string">'新建窗口'</span>,</span><br><span class="line">                click: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">                    <span class="built_in">console</span>.log(<span class="string">'新建窗口'</span>)</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">        label: <span class="string">'编辑'</span>,</span><br><span class="line">        submenu: [</span><br><span class="line">            &#123;</span><br><span class="line">                label: <span class="string">'复制'</span>,</span><br><span class="line">                role: <span class="string">'copy'</span> <span class="comment">// 调用内置角色实现对应功能</span></span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                label: <span class="string">'剪切'</span>,</span><br><span class="line">                role: <span class="string">'cut'</span>  <span class="comment">// 调用内置角色实现对应功能</span></span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">        label: <span class="string">'视图'</span>,</span><br><span class="line">        submenu: [</span><br><span class="line">            &#123;</span><br><span class="line">                label: <span class="string">'浏览'</span></span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                label: <span class="string">'搜索'</span></span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> m = Menu.buildFromTemplate(menus)</span><br><span class="line">Menu.setApplicationMenu(m)</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 在主进程src/index.js中引入</span></span><br><span class="line"><span class="keyword">const</span> createWindow = <span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建菜单  </span></span><br><span class="line">  <span class="comment">// 引入菜单模块</span></span><br><span class="line">  <span class="built_in">require</span>(<span class="string">'./main/menu.js'</span>)</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/55.png" alt></p>
<blockquote>
<p>我们给菜单绑定事件，在命令行控制台可以看到</p>
</blockquote>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/56.png" alt></p>
<h2 id="5-2-渲染进程中调用Menu模块"><a href="#5-2-渲染进程中调用Menu模块" class="headerlink" title="5.2 渲染进程中调用Menu模块"></a>5.2 渲染进程中调用Menu模块</h2><blockquote>
<p>不推荐使用这种方式，建议在主进程中使用</p>
</blockquote>
<p><strong>1. remote</strong></p>
<blockquote>
<p>通过<code>remote</code>调用主进程的方法</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 菜单引入的方式发生变化</span></span><br><span class="line"><span class="keyword">const</span> &#123; Menu &#125;  = <span class="built_in">require</span>(<span class="string">'electron'</span>).remote</span><br><span class="line"></span><br><span class="line"><span class="comment">// 其他代码和上面菜单一样</span></span><br><span class="line"><span class="comment">// ...</span></span><br></pre></td></tr></table></figure>
<p><strong>2. 加入index.html</strong></p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"render/menu.js"</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h2 id="5-3-渲染进程中自定义右键菜单"><a href="#5-3-渲染进程中自定义右键菜单" class="headerlink" title="5.3 渲染进程中自定义右键菜单"></a>5.3 渲染进程中自定义右键菜单</h2><p><strong>1. 定义菜单</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// render/menu.js</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 在渲染进程中通过remote模块调用主进程中的模块</span></span><br><span class="line"><span class="keyword">const</span> &#123; Menu &#125;  = <span class="built_in">require</span>(<span class="string">'electron'</span>).remote</span><br><span class="line"><span class="keyword">const</span> &#123; remote &#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 文档 https://electronjs.org/docs/api/menu-item</span></span><br><span class="line"><span class="comment">// 菜单项目</span></span><br><span class="line"><span class="keyword">let</span> menus = [</span><br><span class="line">    &#123;</span><br><span class="line">        label: <span class="string">'文件'</span>,</span><br><span class="line">        submenu: [</span><br><span class="line">            &#123;</span><br><span class="line">                label: <span class="string">'新建文件'</span>,</span><br><span class="line">                accelerator: <span class="string">'ctrl+n'</span>, <span class="comment">// 绑定快捷键</span></span><br><span class="line">                click: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123; <span class="comment">// 绑定事件</span></span><br><span class="line">                    <span class="built_in">console</span>.log(<span class="string">'新建文件'</span>)</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                label: <span class="string">'新建窗口'</span>,</span><br><span class="line">                click: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">                    <span class="built_in">console</span>.log(<span class="string">'新建窗口'</span>)</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">        label: <span class="string">'编辑'</span>,</span><br><span class="line">        submenu: [</span><br><span class="line">            &#123;</span><br><span class="line">                label: <span class="string">'复制'</span>,</span><br><span class="line">                role: <span class="string">'copy'</span> <span class="comment">// 调用内置角色实现对应功能</span></span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                label: <span class="string">'剪切'</span>,</span><br><span class="line">                role: <span class="string">'cut'</span>  <span class="comment">// 调用内置角色实现对应功能</span></span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">        label: <span class="string">'视图'</span>,</span><br><span class="line">        submenu: [</span><br><span class="line">            &#123;</span><br><span class="line">                label: <span class="string">'浏览'</span></span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                label: <span class="string">'搜索'</span></span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> m = Menu.buildFromTemplate(menus)</span><br><span class="line"><span class="comment">// Menu.setApplicationMenu(m)</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 绑定右键菜单</span></span><br><span class="line"><span class="built_in">window</span>.addEventListener(<span class="string">'contextmenu'</span>, (e)=&gt;&#123;</span><br><span class="line">   e.preventDefault()</span><br><span class="line">   m.popup(&#123;</span><br><span class="line">    <span class="built_in">window</span>: remote.getCurrentWindow()</span><br><span class="line">   &#125;)</span><br><span class="line">&#125;, <span class="literal">false</span>)</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/57.png" alt></p>
<p><strong>2. 引入</strong></p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--index.html--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"render/menu.js"</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h1 id="六、进程通信"><a href="#六、进程通信" class="headerlink" title="六、进程通信"></a>六、进程通信</h1><p><img src="https://poetries1.gitee.io/img-repo/20191001/58.png" alt></p>
<ul>
<li>渲染进程 <a href="https://electronjs.org/docs/api/ipc-renderer" target="_blank" rel="noopener">https://electronjs.org/docs/api/ipc-renderer</a></li>
<li>主进程 <a href="https://electronjs.org/docs/api/ipc-main" target="_blank" rel="noopener">https://electronjs.org/docs/api/ipc-main</a></li>
</ul>
<h2 id="6-1-主进程与渲染进程之间的通信"><a href="#6-1-主进程与渲染进程之间的通信" class="headerlink" title="6.1 主进程与渲染进程之间的通信"></a>6.1 主进程与渲染进程之间的通信</h2><blockquote>
<p>有时候我们想在渲染进程中通过一个事件去执行主进程里面的方法。或者在渲染进程中通知 主进程处理事件，主进程处理完成后广播一个事件让渲染进程去处理一些事情。这个时候就 用到了主进程和渲染进程之间的相互通信</p>
</blockquote>
<blockquote>
<p><code>Electron</code> 主进程，和渲染进程的通信主要用到两个模块:<code>ipcMain</code> 和 <code>ipcRenderer</code></p>
</blockquote>
<ul>
<li><code>ipcMain</code>:当在主进程中使用时，它处理从渲染器进程(网页)发送出来的异步和同步信息,当然也有可能从主进程向渲染进程发送消息。</li>
<li><code>ipcRenderer</code>: 使用它提供的一些方法从渲染进程 (<code>web</code> 页面) 发送同步或异步的消息到主进程。 也可以接收主进程回复的消息</li>
</ul>
<h3 id="6-1-1-渲染进程给主进程发送异步消息"><a href="#6-1-1-渲染进程给主进程发送异步消息" class="headerlink" title="6.1.1 渲染进程给主进程发送异步消息"></a>6.1.1 渲染进程给主进程发送异步消息</h3><blockquote>
<p>间接实现渲染进程执行主进程里面的方法</p>
</blockquote>
<p><strong>1. 引入ipcRender</strong></p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--src/index.html--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">"send"</span>&gt;</span>在 渲染进程中执行主进程里的方法（异步）<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"render/ipcRender.js"</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p><strong>2. 引入ipcMain</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 在主进程src/index.js中引入</span></span><br><span class="line"><span class="keyword">const</span> createWindow = <span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建菜单  </span></span><br><span class="line">  <span class="comment">// 引入菜单模块</span></span><br><span class="line">  <span class="built_in">require</span>(<span class="string">'./main/ipcMain.js'</span>)</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p><strong>3. 渲染进程发送消息</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/render/ipcRender.js</span></span><br><span class="line"><span class="comment">//渲染进程</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> send = <span class="built_in">document</span>.querySelector(<span class="string">'#send'</span>);</span><br><span class="line"><span class="keyword">const</span> &#123; ipcRenderer &#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>);</span><br><span class="line"></span><br><span class="line">send.onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 传递消息给主进程</span></span><br><span class="line">    <span class="comment">// 异步</span></span><br><span class="line">    ipcRenderer.send(<span class="string">'sendMsg'</span>, &#123;<span class="attr">name</span>:<span class="string">'poetries'</span>, <span class="attr">age</span>: <span class="number">23</span>&#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>2. 主进程接收消息</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/main/ipcMain.js</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//主进程</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> &#123; ipcMain &#125;  = <span class="built_in">require</span>(<span class="string">'electron'</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 主进程处理渲染进程广播数据</span></span><br><span class="line">ipcMain.on(<span class="string">'sendMsg'</span>, (event, data)=&gt; &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'data\n '</span>, data)</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'event\n '</span>, event)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/59.png" alt></p>
<h3 id="6-1-2-渲染进程发送消息，主进程接收消息并反馈"><a href="#6-1-2-渲染进程发送消息，主进程接收消息并反馈" class="headerlink" title="6.1.2 渲染进程发送消息，主进程接收消息并反馈"></a>6.1.2 渲染进程发送消息，主进程接收消息并反馈</h3><blockquote>
<p>渲染进程给主进程发送异步消息，主进程接收到异步消息以后通知渲染进程</p>
</blockquote>
<p><strong>1. 引入ipcRender</strong></p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--src/index.html--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">"sendFeedback"</span>&gt;</span>在 渲染进程中执行主进程里的方法，并反馈给主进程（异步）<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"render/ipcRender.js"</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p><strong>2. 引入ipcMain</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 在主进程src/index.js中引入</span></span><br><span class="line"><span class="keyword">const</span> createWindow = <span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建菜单  </span></span><br><span class="line">  <span class="comment">// 引入菜单模块</span></span><br><span class="line">  <span class="built_in">require</span>(<span class="string">'./main/ipcMain.js'</span>)</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p><strong>3. 渲染进程发送消息</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/render/ipcRender.js</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//渲染进程</span></span><br><span class="line"><span class="keyword">let</span> sendFeedback = <span class="built_in">document</span>.querySelector(<span class="string">'#sendFeedback'</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> &#123; ipcRenderer &#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 向主进程发送消息</span></span><br><span class="line">sendFeedback.onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 触发主进程里面的方法</span></span><br><span class="line">    ipcRenderer.send(<span class="string">'sendFeedback'</span>, &#123;<span class="attr">name</span>:<span class="string">'poetries'</span>, <span class="attr">age</span>: <span class="number">23</span>&#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>4. 主进程收到消息处理并广播反馈通知渲染进程</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/main/ipcMain.js</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//主进程</span></span><br><span class="line"><span class="keyword">const</span> &#123; ipcMain &#125;  = <span class="built_in">require</span>(<span class="string">'electron'</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 主进程处理渲染进程广播数据，并反馈给渲染进程</span></span><br><span class="line">ipcMain.on(<span class="string">'sendFeedback'</span>, (event, data)=&gt; &#123;</span><br><span class="line">    <span class="comment">// console.log('data\n ', data)</span></span><br><span class="line">    <span class="comment">// console.log('event\n ', event)</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 主进程给渲染进程广播数据</span></span><br><span class="line">    event.sender.send(<span class="string">'sendFeedbackToRender'</span>, <span class="string">'来自主进程的反馈'</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><strong>5. 渲染进程处理主进程广播的数据</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/render/ipcRender.js</span></span><br><span class="line"><span class="comment">// 向主进程发送消息后，接收主进程广播的事件</span></span><br><span class="line">ipcRenderer.on(<span class="string">'sendFeedbackToRender'</span>, (e, data)=&gt;&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'event\n '</span>, e)</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'data\n '</span>, data)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/60.png" alt></p>
<h3 id="6-1-3-渲染进程给主进程发送同步消息"><a href="#6-1-3-渲染进程给主进程发送同步消息" class="headerlink" title="6.1.3 渲染进程给主进程发送同步消息"></a>6.1.3 渲染进程给主进程发送同步消息</h3><p><strong>1. 引入ipcRender</strong></p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--src/index.html--&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">"sendSync"</span>&gt;</span>渲染进程和主进程同步通信<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"render/ipcRender.js"</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p><strong>2. 引入ipcMain</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 在主进程src/index.js中引入</span></span><br><span class="line"><span class="keyword">const</span> createWindow = <span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建菜单  </span></span><br><span class="line">  <span class="comment">// 引入菜单模块</span></span><br><span class="line">  <span class="built_in">require</span>(<span class="string">'./main/ipcMain.js'</span>)</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p><strong>3. 渲染进程给主进程同步通信</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/render/ipcMain.js</span></span><br><span class="line"><span class="keyword">let</span> sendSync = <span class="built_in">document</span>.querySelector(<span class="string">'#sendSync'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 渲染进程和主进程同步通信</span></span><br><span class="line">sendSync.onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 同步广播数据</span></span><br><span class="line">   <span class="keyword">let</span> msg =  ipcRenderer.sendSync(<span class="string">'sendsync'</span>, &#123;<span class="attr">name</span>:<span class="string">'poetries'</span>, <span class="attr">age</span>: <span class="number">23</span>&#125;)</span><br><span class="line">    </span><br><span class="line">   <span class="comment">// 同步返回主进程反馈的数据</span></span><br><span class="line">   <span class="built_in">console</span>.log(<span class="string">'msg\n '</span>, msg)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>4. 主进程接收数据处理</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/main/ipcMain.js</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 渲染进程和主进程同步通信 接收同步广播</span></span><br><span class="line">ipcMain.on(<span class="string">'sendsync'</span>, (event, data)=&gt; &#123;</span><br><span class="line">    <span class="comment">// console.log('data\n ', data)</span></span><br><span class="line">    <span class="comment">// console.log('event\n ', event)</span></span><br><span class="line">    <span class="comment">// 主进程给渲染进程广播数据</span></span><br><span class="line">    event.returnValue =<span class="string">'渲染进程和主进程同步通信 接收同步广播，来自主进程的反馈.'</span>;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/61.png" alt></p>
<h3 id="6-1-4-渲染进程广播通知主进程打开窗口"><a href="#6-1-4-渲染进程广播通知主进程打开窗口" class="headerlink" title="6.1.4 渲染进程广播通知主进程打开窗口"></a>6.1.4 渲染进程广播通知主进程打开窗口</h3><blockquote>
<p>一般都是在渲染进程中执行广播操作，去通知主进程完成任务</p>
</blockquote>
<p><strong>1. 引入openWindow</strong></p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--src/index.html--&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">"sendSync"</span>&gt;</span>渲染进程和主进程同步通信<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"render/openWindow.js"</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p><strong>2. 引入ipcMain2</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 在主进程src/index.js中引入</span></span><br><span class="line"><span class="keyword">const</span> createWindow = <span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建菜单  </span></span><br><span class="line">  <span class="comment">// 引入菜单模块</span></span><br><span class="line">  <span class="built_in">require</span>(<span class="string">'./main/ipcMain2.js'</span>)</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p><strong>3. 渲染进程通知主进程打开窗口</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/render/openWindow.js</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* eslint-disable */</span></span><br><span class="line"><span class="keyword">let</span> openWindow = <span class="built_in">document</span>.querySelector(<span class="string">'#openWindow'</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> &#123; ipcRenderer &#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 渲染进程和渲染进程直接的通信========</span></span><br><span class="line">openWindow.onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 通过广播的形式 通知主进程执行操作</span></span><br><span class="line">    ipcRenderer.send(<span class="string">'openwindow'</span>, &#123;<span class="attr">name</span>:<span class="string">'poetries'</span>, <span class="attr">age</span>: <span class="number">23</span>&#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>4. 主进程收到通知执行操作</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/main/ipcMain2.js</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* eslint-disable */</span></span><br><span class="line"><span class="keyword">let</span> &#123; ipcMain,BrowserWindow &#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>)</span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> win;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 接收到广播</span></span><br><span class="line">ipcMain.on(<span class="string">'openwindow'</span>, (e, data)=&gt; &#123;</span><br><span class="line">    <span class="comment">// 调用window打开新窗口</span></span><br><span class="line">    win = <span class="keyword">new</span> BrowserWindow(&#123;</span><br><span class="line">        width: <span class="number">400</span>,</span><br><span class="line">        height: <span class="number">300</span>,</span><br><span class="line">    &#125;);</span><br><span class="line">    win.loadURL(path.join(<span class="string">'file:'</span>,__dirname, <span class="string">'../news.html'</span>));</span><br><span class="line">    win.webContents.openDevTools()</span><br><span class="line">    win.on(<span class="string">'closed'</span>, () =&gt; &#123;</span><br><span class="line">        win = <span class="literal">null</span>;</span><br><span class="line">      &#125;);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/62.png" alt></p>
<h2 id="6-2-渲染进程与渲染进程之间的通信"><a href="#6-2-渲染进程与渲染进程之间的通信" class="headerlink" title="6.2 渲染进程与渲染进程之间的通信"></a>6.2 渲染进程与渲染进程之间的通信</h2><blockquote>
<p>也就是两个窗口直接的通信</p>
</blockquote>
<h3 id="6-2-1-localstorage传值"><a href="#6-2-1-localstorage传值" class="headerlink" title="6.2.1 localstorage传值"></a>6.2.1 localstorage传值</h3><blockquote>
<p><code>Electron</code> 渲染进程通过 <code>localstorage</code> 给另一个渲染进程传值</p>
</blockquote>
<p><strong>1. 引入openWindow</strong></p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--src/index.html--&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">"sendSync"</span>&gt;</span>渲染进程和主进程同步通信<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"render/openWindow.js"</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p><strong>2. 引入ipcMain2</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 在主进程src/index.js中引入</span></span><br><span class="line"><span class="keyword">const</span> createWindow = <span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建菜单  </span></span><br><span class="line">  <span class="comment">// 引入菜单模块</span></span><br><span class="line">  <span class="built_in">require</span>(<span class="string">'./main/ipcMain2.js'</span>)</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p><strong>3. 渲染进程通知主进程打开窗口</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/render/openWindow.js</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* eslint-disable */</span></span><br><span class="line"><span class="keyword">let</span> openWindow = <span class="built_in">document</span>.querySelector(<span class="string">'#openWindow'</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> &#123; ipcRenderer &#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 渲染进程和渲染进程直接的通信========</span></span><br><span class="line">openWindow.onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 通过广播的形式 通知主进程执行操作</span></span><br><span class="line">    ipcRenderer.send(<span class="string">'openwindow'</span>, &#123;<span class="attr">name</span>:<span class="string">'poetries'</span>, <span class="attr">age</span>: <span class="number">23</span>&#125;)</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// ======= localstorage传值 =====</span></span><br><span class="line">     localStorage.setItem(<span class="string">'username'</span>, <span class="string">'poetries'</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>4. 新建news页面</strong></p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--src/news.html--&gt;</span></span><br><span class="line"><span class="meta">&lt;!DOCTYPE <span class="meta-keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">"utf-8"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span><span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    news page</span><br><span class="line">  <span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"render/news.js"</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/render/news.js</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> username = localStorage.getItem(<span class="string">'username'</span>)</span><br><span class="line"><span class="built_in">console</span>.log(username)</span><br></pre></td></tr></table></figure>
<p><strong>5. 主进程收到通知执行操作</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/main/ipcMain2.js</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* eslint-disable */</span></span><br><span class="line"><span class="keyword">let</span> &#123; ipcMain,BrowserWindow &#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>)</span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> win;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 接收到广播</span></span><br><span class="line">ipcMain.on(<span class="string">'openwindow'</span>, (e, data)=&gt; &#123;</span><br><span class="line">    <span class="comment">// 调用window打开新窗口</span></span><br><span class="line">    win = <span class="keyword">new</span> BrowserWindow(&#123;</span><br><span class="line">        width: <span class="number">400</span>,</span><br><span class="line">        height: <span class="number">300</span>,</span><br><span class="line">    &#125;);</span><br><span class="line">    win.loadURL(path.join(<span class="string">'file:'</span>,__dirname, <span class="string">'../news.html'</span>));</span><br><span class="line">    win.webContents.openDevTools()</span><br><span class="line">    win.on(<span class="string">'closed'</span>, () =&gt; &#123;</span><br><span class="line">        win = <span class="literal">null</span>;</span><br><span class="line">      &#125;);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h3 id="6-2-2-BrowserWindow和webContents方式实现"><a href="#6-2-2-BrowserWindow和webContents方式实现" class="headerlink" title="6.2.2 BrowserWindow和webContents方式实现"></a>6.2.2 BrowserWindow和webContents方式实现</h3><blockquote>
<p>通过 <code>BrowserWindow</code> 和 <code>webContents</code> 模块实现渲染进程和渲染进程的通信</p>
</blockquote>
<blockquote>
<p><code>webContents</code> 是一个事件发出者.它负责渲染并控制网页，也是 <code>BrowserWindow</code> 对象的属性</p>
</blockquote>
<p><strong>需要了解的几个知识点</strong></p>
<ol>
<li>获取当前窗口的 <code>id</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> winId = BrowserWindow.getFocusedWindow().id;</span><br></pre></td></tr></table></figure>
<ol start="2">
<li>监听当前窗口加载完成的事件</li>
</ol>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">win.webContents.on(<span class="string">'did-finish-load'</span>,(event) =&gt; &#123;</span><br><span class="line">    </span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol start="3">
<li>同一窗口之间广播数据</li>
</ol>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">win.webContents.on(<span class="string">'did-finish-load'</span>,(event) =&gt; &#123;</span><br><span class="line">    win.webContents.send(<span class="string">'msg'</span>,winId,<span class="string">'我是 index.html 的数据'</span>);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol start="4">
<li>通过 <code>id</code> 查找窗口</li>
</ol>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">let</span> win = BrowserWindow.fromId(winId);</span><br></pre></td></tr></table></figure>
<blockquote>
<p>下面是具体演示</p>
</blockquote>
<p><strong>1. 引入openWindow</strong></p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--src/index.html--&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">"sendSync"</span>&gt;</span>渲染进程和主进程同步通信<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"render/openWindow.js"</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p><strong>2. 引入ipcMain2</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 在主进程src/index.js中引入</span></span><br><span class="line"><span class="keyword">const</span> createWindow = <span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建菜单  </span></span><br><span class="line">  <span class="comment">// 引入菜单模块</span></span><br><span class="line">  <span class="built_in">require</span>(<span class="string">'./main/ipcMain2.js'</span>)</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p><strong>3. 渲染进程通知主进程打开窗口</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/render/openWindow.js</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* eslint-disable */</span></span><br><span class="line"><span class="keyword">let</span> openWindow = <span class="built_in">document</span>.querySelector(<span class="string">'#openWindow'</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> &#123; ipcRenderer &#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 渲染进程和渲染进程直接的通信========</span></span><br><span class="line">openWindow.onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 通过广播的形式 通知主进程执行操作</span></span><br><span class="line">    ipcRenderer.send(<span class="string">'openwindow'</span>, &#123;<span class="attr">name</span>:<span class="string">'poetries'</span>, <span class="attr">age</span>: <span class="number">23</span>&#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>4. 主进程收到通知执行操作</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/main/ipcMain2.js</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> &#123; ipcMain,BrowserWindow &#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>)</span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> win;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 接收到广播</span></span><br><span class="line">ipcMain.on(<span class="string">'openwindow'</span>, (e, userInfo)=&gt; &#123;</span><br><span class="line">    <span class="comment">// 调用window打开新窗口</span></span><br><span class="line">    win = <span class="keyword">new</span> BrowserWindow(&#123;</span><br><span class="line">        width: <span class="number">400</span>,</span><br><span class="line">        height: <span class="number">300</span>,</span><br><span class="line">    &#125;);</span><br><span class="line">    win.loadURL(path.join(<span class="string">'file:'</span>,__dirname, <span class="string">'../news.html'</span>));</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 新开窗口调试模式</span></span><br><span class="line">    win.webContents.openDevTools()</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 把渲染进程传递过来的数据再次传递给渲染进程news</span></span><br><span class="line">    <span class="comment">// 等待窗口加载完</span></span><br><span class="line">    win.webContents.on(<span class="string">'did-finish-load'</span>, ()=&gt;[</span><br><span class="line">        win.webContents.send(<span class="string">'toNews'</span>, userInfo)</span><br><span class="line">    ])</span><br><span class="line">    </span><br><span class="line"></span><br><span class="line">    win.on(<span class="string">'closed'</span>, () =&gt; &#123;</span><br><span class="line">        win = <span class="literal">null</span>;</span><br><span class="line">      &#125;);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><strong>5. news接收主进程传递的数据</strong></p>
<blockquote>
<p>数据经过渲染进程-&gt;主进程-&gt;<code>news</code>渲染进程</p>
</blockquote>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--news页面--&gt;</span></span><br><span class="line"><span class="meta">&lt;!DOCTYPE <span class="meta-keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">"utf-8"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span><span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    news page</span><br><span class="line">  <span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"render/news.js"</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/render/news.js</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> &#123; ipcRenderer &#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// let username = localStorage.getItem('username')</span></span><br><span class="line"><span class="comment">// console.log(username)</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 监听主进程传递过来的数据 </span></span><br><span class="line">ipcRenderer.on(<span class="string">'toNews'</span>,(e, userInfo)=&gt;&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(userInfo)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/63.png" alt></p>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/64.png" alt></p>
<blockquote>
<p>那么，这里有一个问题，<code>news</code>进程接收到了广播后如何给出反馈呢？</p>
</blockquote>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/65.png" alt></p>
<p><strong>1. 在主进程中获取窗口ID传递</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/main/ipcMain2.js</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> &#123; ipcMain,BrowserWindow &#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>)</span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> win;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 接收到广播</span></span><br><span class="line">ipcMain.on(<span class="string">'openwindow'</span>, (e, userInfo)=&gt; &#123;</span><br><span class="line">      <span class="comment">// 获取当前窗口ID 放在第一行保险  因为后面也打开了新窗口使得获取的ID有问题</span></span><br><span class="line">    <span class="keyword">let</span> winId = BrowserWindow.getFocusedWindow().id</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 调用window打开新窗口</span></span><br><span class="line">    win = <span class="keyword">new</span> BrowserWindow(&#123;</span><br><span class="line">        width: <span class="number">400</span>,</span><br><span class="line">        height: <span class="number">300</span>,</span><br><span class="line">    &#125;);</span><br><span class="line">    win.loadURL(path.join(<span class="string">'file:'</span>,__dirname, <span class="string">'../news.html'</span>));</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 新开窗口调试模式</span></span><br><span class="line">    win.webContents.openDevTools()</span><br><span class="line"></span><br><span class="line">  </span><br><span class="line"></span><br><span class="line">    <span class="comment">// 把渲染进程传递过来的数据再次传递给渲染进程news</span></span><br><span class="line">    <span class="comment">// 等待窗口加载完</span></span><br><span class="line">    win.webContents.on(<span class="string">'did-finish-load'</span>, ()=&gt;[</span><br><span class="line">        win.webContents.send(<span class="string">'toNews'</span>, userInfo, winId)</span><br><span class="line">    ])</span><br><span class="line">    </span><br><span class="line"></span><br><span class="line">    win.on(<span class="string">'closed'</span>, () =&gt; &#123;</span><br><span class="line">        win = <span class="literal">null</span>;</span><br><span class="line">      &#125;);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><strong>2. 在news进程中广播数据</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/render/news.js</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> &#123; ipcRenderer &#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 注意这里 在渲染进程中需要从remote中获取BrowserWindow</span></span><br><span class="line"><span class="keyword">const</span> BrowerWindow = <span class="built_in">require</span>(<span class="string">'electron'</span>).remote.BrowserWindow;</span><br><span class="line"></span><br><span class="line"><span class="comment">// let username = localStorage.getItem('username')</span></span><br><span class="line"><span class="comment">// console.log(username)</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 监听主进程传递过来的数据 </span></span><br><span class="line">ipcRenderer.on(<span class="string">'toNews'</span>,(e, userInfo, winId)=&gt;&#123;</span><br><span class="line">    <span class="comment">// windID 第一个窗口ID</span></span><br><span class="line">    <span class="comment">// 获取对应ID的窗口</span></span><br><span class="line">    <span class="keyword">let</span> firstWin = BrowerWindow.fromId(winId)</span><br><span class="line">    firstWin.webContents.send(<span class="string">'toIndex'</span>, <span class="string">'来自news进程反馈的信息'</span>)</span><br><span class="line">    <span class="built_in">console</span>.log(userInfo)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><strong>3. 在另一个渲染进程中处理广播</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">/* eslint-disable */</span></span><br><span class="line"><span class="keyword">let</span> openWindow = <span class="built_in">document</span>.querySelector(<span class="string">'#openWindow'</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> &#123; ipcRenderer &#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 渲染进程和渲染进程直接的通信========</span></span><br><span class="line">openWindow.onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 传递消息给主进程</span></span><br><span class="line">    ipcRenderer.send(<span class="string">'openwindow'</span>, &#123;<span class="attr">name</span>:<span class="string">'poetries'</span>, <span class="attr">age</span>: <span class="number">23</span>&#125;)</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 传递给打开的窗口 渲染进程和渲染进程直接的通信</span></span><br><span class="line">    localStorage.setItem(<span class="string">'username'</span>, <span class="string">'poetries'</span>)</span><br><span class="line">    </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 接收news渲染进程传递回来的消息</span></span><br><span class="line">ipcRenderer.on(<span class="string">'toIndex'</span>, (e, data)=&gt;&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'==='</span>, data)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/66.png" alt></p>
<h1 id="七、Electron-Shell-模块"><a href="#七、Electron-Shell-模块" class="headerlink" title="七、Electron Shell 模块"></a>七、Electron Shell 模块</h1><p><img src="https://poetries1.gitee.io/img-repo/20191001/67.png" alt></p>
<h2 id="7-1-Shell-模块使用"><a href="#7-1-Shell-模块使用" class="headerlink" title="7.1 Shell 模块使用"></a>7.1 Shell 模块使用</h2><blockquote>
<p>文档 <a href="https://electronjs.org/docs/api/shell" target="_blank" rel="noopener">https://electronjs.org/docs/api/shell</a></p>
</blockquote>
<blockquote>
<p><code>Electron Shell</code> 模块在用户默认浏览器 中打开 <code>URL</code> 以及 <code>Electron DOM webview</code> 标签。<code>Shell</code>既属于主进程模块又是渲染进程模块</p>
</blockquote>
<blockquote>
<p><code>shell</code> 模块提供了集成其他桌面客户端的关联功能</p>
</blockquote>
<p><strong>1. 引入</strong></p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--index.html--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">"shellDom"</span>&gt;</span>通过shell打开外部链接<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"render/shell.js"</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p><strong>2. shell.js</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/render/shell.js</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> &#123; shell &#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>)</span><br><span class="line"><span class="keyword">let</span> shellDom = <span class="built_in">document</span>.querySelector(<span class="string">'#shellDom'</span>);</span><br><span class="line"></span><br><span class="line">shellDom.onclick = <span class="function"><span class="keyword">function</span> (<span class="params">e</span>) </span>&#123;</span><br><span class="line">   shell.openExternal(<span class="string">'https://github.com/poetries'</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="7-2-Electron-DOM-lt-webview-gt-标签"><a href="#7-2-Electron-DOM-lt-webview-gt-标签" class="headerlink" title="7.2 Electron DOM &lt;webview&gt; 标签"></a>7.2 <code>Electron DOM</code> <code>&lt;webview&gt;</code> 标签</h2><blockquote>
<p><code>Webview</code> 与 <code>iframe</code> 有点相似，但是与 <code>iframe</code> 不同, <code>webview</code> 和你的应用运行的是不同的进程。它不拥有渲染进程的权限，并且应用和嵌入内容之间的交互全部都是异步的。因为这能 保证应用的安全性不受嵌入内容的影响。</p>
</blockquote>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--src/index.html中引入--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">webview</span> <span class="attr">id</span>=<span class="string">"webview"</span> <span class="attr">src</span>=<span class="string">"http://blog.poetries.top"</span> <span class="attr">style</span>=<span class="string">"position:fixed; width:100%; height:100%"</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">webview</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h2 id="7-3-shell模块-lt-webview-gt-结合Menu模块使用案例"><a href="#7-3-shell模块-lt-webview-gt-结合Menu模块使用案例" class="headerlink" title="7.3 shell模块&lt;webview&gt;结合Menu模块使用案例"></a>7.3 <code>shell</code>模块<code>&lt;webview&gt;</code>结合<code>Menu</code>模块使用案例</h2><p><strong>1. 新建src/render/webview.js</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">/* eslint-disable */</span></span><br><span class="line"><span class="keyword">var</span> &#123; ipcRenderer &#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>);</span><br><span class="line"><span class="keyword">let</span> myWebview = <span class="built_in">document</span>.querySelector(<span class="string">'#myWebview'</span>)</span><br><span class="line"></span><br><span class="line">ipcRenderer.on(<span class="string">'openwebview'</span>, (e, url)=&gt;&#123;</span><br><span class="line">    myWebview.src = url</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><strong>2. 引入src/index.html</strong></p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">webview</span> <span class="attr">id</span>=<span class="string">"myWebview"</span> <span class="attr">src</span>=<span class="string">"http://blog.poetries.top"</span> <span class="attr">style</span>=<span class="string">"position:fixed; width:100%; height:100%"</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">webview</span>&gt;</span></span><br><span class="line">    </span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"render/webview.js"</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p><strong>3. 新建src/main/menu.js</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">/* eslint-disable */</span></span><br><span class="line"><span class="keyword">const</span> &#123; shell, Menu, BrowserWindow &#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 当前窗口渲染网页</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">openWebView</span>(<span class="params">url</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 获取当前窗口Id</span></span><br><span class="line">    <span class="keyword">let</span> win = BrowserWindow.getFocusedWindow()</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 广播通知渲染进程打开webview</span></span><br><span class="line">    win.webContents.send(<span class="string">'openwebview'</span>, url)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 在窗口外打开网页</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">openWeb</span>(<span class="params">url</span>) </span>&#123;</span><br><span class="line">    shell.openExternal(url)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> template = [</span><br><span class="line">    &#123;</span><br><span class="line">        label: <span class="string">'帮助'</span>,</span><br><span class="line">        submenu: [</span><br><span class="line">            &#123;</span><br><span class="line">                label: <span class="string">'关于我们'</span>,</span><br><span class="line">                click: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">                    openWeb(<span class="string">'http://blog.poetries.top'</span>)</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                type: <span class="string">'separator'</span></span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                label: <span class="string">'联系我们'</span>,</span><br><span class="line">                click: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">                    openWeb(<span class="string">'https://github.com/poetries'</span>)</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;,</span><br><span class="line">   &#123;</span><br><span class="line">        label: <span class="string">'加载网页'</span>,</span><br><span class="line">        submenu: [</span><br><span class="line">            &#123;</span><br><span class="line">                label: <span class="string">'博客'</span>,</span><br><span class="line">                click: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">                    openWebView(<span class="string">'http://blog.poetries.top'</span>)</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                type: <span class="string">'separator'</span> <span class="comment">// 分隔符</span></span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                label: <span class="string">'GitHub'</span>,</span><br><span class="line">                click: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">                    openWebView(<span class="string">'https://github.com/poetries'</span>)</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                type: <span class="string">'separator'</span> <span class="comment">// 分隔符</span></span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                label: <span class="string">'简书'</span>,</span><br><span class="line">                click: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">                    openWebView(<span class="string">'https://www.jianshu.com/users/94077fcddfc0/timeline'</span>)</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">   &#125;,</span><br><span class="line">   &#123;</span><br><span class="line">    label: <span class="string">'视频网站'</span>,</span><br><span class="line">    submenu: [</span><br><span class="line">        &#123;</span><br><span class="line">            label: <span class="string">'优酷'</span>,</span><br><span class="line">            click: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">                openWebView(<span class="string">'https://www.youku.com'</span>)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">            type: <span class="string">'separator'</span> <span class="comment">// 分隔符</span></span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">            label: <span class="string">'爱奇艺'</span>,</span><br><span class="line">            click: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">                openWebView(<span class="string">'https://www.iqiyi.com/'</span>)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">            type: <span class="string">'separator'</span> <span class="comment">// 分隔符</span></span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">            label: <span class="string">'腾讯视频'</span>,</span><br><span class="line">            click: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">                openWebView(<span class="string">'https://v.qq.com/'</span>)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    ]</span><br><span class="line">    &#125;</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> m = Menu.buildFromTemplate(template)</span><br><span class="line">Menu.setApplicationMenu(m)</span><br></pre></td></tr></table></figure>
<p><strong>4. 引入menu</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 在主进程src/index.js中引入</span></span><br><span class="line"><span class="keyword">const</span> createWindow = <span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建菜单  </span></span><br><span class="line">  <span class="comment">// 引入菜单模块</span></span><br><span class="line">  <span class="built_in">require</span>(<span class="string">'./main/menu.js'</span>)</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/68.png" alt></p>
<h1 id="八、Electron-dialog-弹出框"><a href="#八、Electron-dialog-弹出框" class="headerlink" title="八、Electron dialog 弹出框"></a>八、Electron dialog 弹出框</h1><p><img src="https://poetries1.gitee.io/img-repo/20191001/69.png" alt></p>
<blockquote>
<p>文档 <a href="https://electronjs.org/docs/api/dialog" target="_blank" rel="noopener">https://electronjs.org/docs/api/dialog</a></p>
</blockquote>
<blockquote>
<p><code>dialog</code>属于主进程中的模块</p>
</blockquote>
<blockquote>
<p><code>dialog</code> 模块提供了 <code>api</code> 来展示原生的系统对话框，例如打开文件框，<code>alert</code> 框， 所以 <code>web</code> 应用可以给用户带来跟系统应用相同的体验</p>
</blockquote>
<p><strong>1. 在src/index.html中引入</strong></p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">"showError"</span>&gt;</span>showError<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">"showMsg"</span>&gt;</span>showMsg<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">"showOpenDialog"</span>&gt;</span>showOpenDialog<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">"saveDialog"</span>&gt;</span>saveDialog<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"render/dialog.js"</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p><strong>2. 新建render/dialog.js</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// render/dialog.js</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> showError = <span class="built_in">document</span>.querySelector(<span class="string">'#showError'</span>);</span><br><span class="line"><span class="keyword">let</span> showMsg = <span class="built_in">document</span>.querySelector(<span class="string">'#showMsg'</span>);</span><br><span class="line"><span class="keyword">let</span> showOpenDialog = <span class="built_in">document</span>.querySelector(<span class="string">'#showOpenDialog'</span>);</span><br><span class="line"><span class="keyword">let</span> saveDialog = <span class="built_in">document</span>.querySelector(<span class="string">'#saveDialog'</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> &#123;remote&#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>)</span><br><span class="line"></span><br><span class="line">showError.onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    remote.dialog.showErrorBox(<span class="string">'警告'</span>, <span class="string">'操作有误'</span>)</span><br><span class="line">&#125;</span><br><span class="line">showMsg.onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    remote.dialog.showMessageBox(&#123;</span><br><span class="line">        type: <span class="string">'info'</span>,</span><br><span class="line">        title: <span class="string">'提示信息'</span>,</span><br><span class="line">        message: <span class="string">'内容'</span>,</span><br><span class="line">        buttons: [<span class="string">'确定'</span>, <span class="string">'取消'</span>]</span><br><span class="line">    &#125;,<span class="function"><span class="keyword">function</span>(<span class="params">index</span>)</span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(index)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br><span class="line">showOpenDialog.onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    remote.dialog.showOpenDialog(&#123;</span><br><span class="line">        <span class="comment">// 打开文件夹</span></span><br><span class="line">        properties: [<span class="string">'openDirectory'</span>, <span class="string">'openFile'</span>]</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 打开文件</span></span><br><span class="line">        <span class="comment">// properties: ['openFile']</span></span><br><span class="line">    &#125;, <span class="function"><span class="keyword">function</span> (<span class="params">data</span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(data)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br><span class="line">saveDialog.onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    remote.dialog.showSaveDialog(&#123;</span><br><span class="line">        title: <span class="string">'Save File'</span>,</span><br><span class="line">        defaultPath: <span class="string">'/Users/poetry/Downloads/'</span>,</span><br><span class="line">        <span class="comment">// filters 指定一个文件类型数组，用于规定用户可见或可选的特定类型范围</span></span><br><span class="line">        filters: [</span><br><span class="line">            &#123; <span class="attr">name</span>: <span class="string">'Images'</span>, <span class="attr">extensions</span>: [<span class="string">'jpg'</span>, <span class="string">'png'</span>, <span class="string">'gif'</span>] &#125;,</span><br><span class="line">            &#123; <span class="attr">name</span>: <span class="string">'Movies'</span>, <span class="attr">extensions</span>: [<span class="string">'mkv'</span>, <span class="string">'avi'</span>, <span class="string">'mp4'</span>] &#125;,</span><br><span class="line">            &#123; <span class="attr">name</span>: <span class="string">'Custom File Type'</span>, <span class="attr">extensions</span>: [<span class="string">'as'</span>] &#125;,</span><br><span class="line">            &#123; <span class="attr">name</span>: <span class="string">'All Files'</span>, <span class="attr">extensions</span>: [<span class="string">'*'</span>] &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;, <span class="function"><span class="keyword">function</span> (<span class="params">path</span>) </span>&#123;</span><br><span class="line">        <span class="comment">// 不是真的保存 ，具体还需nodejs处理</span></span><br><span class="line">        <span class="built_in">console</span>.log(path)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>showError</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">remote.dialog.showErrorBox(<span class="string">'警告'</span>, <span class="string">'操作有误'</span>)</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/70.png" alt></p>
<p><strong>showMessageBox</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">remote.dialog.showMessageBox(&#123;</span><br><span class="line">    type: <span class="string">'info'</span>,</span><br><span class="line">    title: <span class="string">'提示信息'</span>,</span><br><span class="line">    message: <span class="string">'内容'</span>,</span><br><span class="line">    buttons: [<span class="string">'确定'</span>, <span class="string">'取消'</span>]</span><br><span class="line">&#125;,<span class="function"><span class="keyword">function</span>(<span class="params">index</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(index)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/71.png" alt></p>
<p><strong>showOpenDialog</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">remote.dialog.showOpenDialog(&#123;</span><br><span class="line">    <span class="comment">// 打开文件夹</span></span><br><span class="line">    properties: [<span class="string">'openDirectory'</span>, <span class="string">'openFile'</span>]</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 打开文件</span></span><br><span class="line">    <span class="comment">// properties: ['openFile']</span></span><br><span class="line">&#125;, <span class="function"><span class="keyword">function</span> (<span class="params">data</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(data)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/72.png" alt></p>
<p><strong>showSaveDialog</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">remote.dialog.showSaveDialog(&#123;</span><br><span class="line">    title: <span class="string">'Save File'</span>,</span><br><span class="line">    defaultPath: <span class="string">'/Users/poetry/Downloads/'</span>,</span><br><span class="line">    <span class="comment">// filters 指定一个文件类型数组，用于规定用户可见或可选的特定类型范围</span></span><br><span class="line">    filters: [</span><br><span class="line">        &#123; <span class="attr">name</span>: <span class="string">'Images'</span>, <span class="attr">extensions</span>: [<span class="string">'jpg'</span>, <span class="string">'png'</span>, <span class="string">'gif'</span>] &#125;,</span><br><span class="line">        &#123; <span class="attr">name</span>: <span class="string">'Movies'</span>, <span class="attr">extensions</span>: [<span class="string">'mkv'</span>, <span class="string">'avi'</span>, <span class="string">'mp4'</span>] &#125;,</span><br><span class="line">        &#123; <span class="attr">name</span>: <span class="string">'Custom File Type'</span>, <span class="attr">extensions</span>: [<span class="string">'as'</span>] &#125;,</span><br><span class="line">        &#123; <span class="attr">name</span>: <span class="string">'All Files'</span>, <span class="attr">extensions</span>: [<span class="string">'*'</span>] &#125;</span><br><span class="line">    ]</span><br><span class="line">&#125;, <span class="function"><span class="keyword">function</span> (<span class="params">path</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 不是真的保存 ，具体还需nodejs处理</span></span><br><span class="line">    <span class="built_in">console</span>.log(path)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/73.png" alt></p>
<h1 id="九、实现一个类似EditPlus的简易记事本代码编辑器"><a href="#九、实现一个类似EditPlus的简易记事本代码编辑器" class="headerlink" title="九、实现一个类似EditPlus的简易记事本代码编辑器"></a>九、实现一个类似EditPlus的简易记事本代码编辑器</h1><blockquote>
<p>代码 <a href="https://github.com/poetries/electron-demo/tree/master/notepad" target="_blank" rel="noopener">https://github.com/poetries/electron-demo/tree/master/notepad</a></p>
</blockquote>
<h1 id="十、系统托盘、托盘右键菜单、托盘图标闪烁"><a href="#十、系统托盘、托盘右键菜单、托盘图标闪烁" class="headerlink" title="十、系统托盘、托盘右键菜单、托盘图标闪烁"></a>十、系统托盘、托盘右键菜单、托盘图标闪烁</h1><p><img src="https://poetries1.gitee.io/img-repo/20191001/74.png" alt></p>
<blockquote>
<p>文档 <a href="https://electronjs.org/docs/api/tray" target="_blank" rel="noopener">https://electronjs.org/docs/api/tray</a></p>
</blockquote>
<blockquote>
<p>系统托盘，托盘右键菜单、托盘图标闪烁 点击右上角关闭按钮隐藏到托盘(仿杀毒软件)</p>
</blockquote>
<p><strong>1. 引入文件</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/index.js</span></span><br><span class="line"><span class="keyword">const</span> createWindow = <span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="built_in">require</span>(<span class="string">'./main/tray.js'</span>)</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p><strong>2. Electron 创建任务栏图标以及任务栏图标右键菜单</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/main/tray.js</span></span><br><span class="line"><span class="keyword">var</span> &#123;</span><br><span class="line">    Menu, Tray, app, BrowserWindow</span><br><span class="line">&#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> appIcon = <span class="keyword">new</span> Tray(path.join(__dirname, <span class="string">'../static/lover.png'</span>));</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> menu = Menu.buildFromTemplate([</span><br><span class="line">    &#123;</span><br><span class="line">        label: <span class="string">'设置'</span>,</span><br><span class="line">        click: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125; <span class="comment">//打开相应页面 </span></span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">        label: <span class="string">'帮助'</span>,</span><br><span class="line">        click: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">        label: <span class="string">'关于'</span>,</span><br><span class="line">        click: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">        label: <span class="string">'退出'</span>,</span><br><span class="line">        click: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123; </span><br><span class="line">            <span class="comment">// BrowserWindow.getFocusedWindow().webContents().send('close-main-window');</span></span><br><span class="line">            app.quit();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;])</span><br><span class="line"><span class="comment">// 鼠标放上去提示信息</span></span><br><span class="line">appIcon.setToolTip(<span class="string">'hello poetries'</span>);</span><br><span class="line">appIcon.setContextMenu(menu);</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/75.png" alt></p>
<p><strong>3. 监听任务栏图标的单击、双击事件</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 实现点击关闭按钮，让应用保存在托盘里面，双击托盘打开</span></span><br><span class="line"><span class="keyword">let</span> win = BrowserWindow.getFocusedWindow()</span><br><span class="line"></span><br><span class="line">win.on(<span class="string">'close'</span>, (e)=&gt;&#123;</span><br><span class="line">    e.preventDefault()</span><br><span class="line">    win.hide()</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">iconTray.on(<span class="string">'double-click'</span>, (e)=&gt;&#123;</span><br><span class="line">    win.show()</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><strong>4. Electron 点击右上角关闭按钮隐藏任务栏图标</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> win = BrowserWindow.getFocusedWindow();</span><br><span class="line"></span><br><span class="line">win.on(<span class="string">'close'</span>, (e) =&gt;&#123;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">console</span>.log(win.isFocused());</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">if</span> (!win.isFocused()) &#123;</span><br><span class="line">        win = <span class="literal">null</span>;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        e.preventDefault();<span class="comment">/*阻止应用退出*/</span></span><br><span class="line">        win.hide();<span class="comment">/*隐藏当前窗口*/</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><strong>5. Electron 实现任务栏闪烁图标</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> appIcon = <span class="keyword">new</span> Tray(path.join(__dirname, <span class="string">'../static/lover.png'</span>));</span><br><span class="line"></span><br><span class="line">timer = setInterval(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    count++;</span><br><span class="line">    <span class="keyword">if</span> (count % <span class="number">2</span> == <span class="number">0</span>) &#123;</span><br><span class="line">        appIcon.setImage(path.join(__dirname, <span class="string">'../static/empty.ico'</span>))</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        appIcon.setImage(path.join(__dirname, <span class="string">'../static/lover.png'</span>))</span><br><span class="line">    &#125;</span><br><span class="line">&#125;,</span><br><span class="line"><span class="number">500</span>);</span><br></pre></td></tr></table></figure>
<h1 id="十一、消息通知、监听网络变-化、网络变化弹出通知框"><a href="#十一、消息通知、监听网络变-化、网络变化弹出通知框" class="headerlink" title="十一、消息通知、监听网络变 化、网络变化弹出通知框"></a>十一、消息通知、监听网络变 化、网络变化弹出通知框</h1><h2 id="11-1-消息通知"><a href="#11-1-消息通知" class="headerlink" title="11.1 消息通知"></a>11.1 消息通知</h2><p><strong>1. Electron 实现消息通知</strong></p>
<blockquote>
<p><code>Electron</code> 里面的消息通知是基于 <code>h5</code> 的通知 <code>api</code> 实现的</p>
</blockquote>
<blockquote>
<p>文档 <a href="https://developer.mozilla.org/zh-CN/docs/Web/API/notification" target="_blank" rel="noopener">https://developer.mozilla.org/zh-CN/docs/Web/API/notification</a></p>
</blockquote>
<p><strong>1. 新建notification.js</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// h5api实现通知</span></span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> options = &#123;</span><br><span class="line">    title: <span class="string">'electron 通知API'</span>,</span><br><span class="line">    body: <span class="string">'hello poetries'</span>,</span><br><span class="line">    icon: path.join(<span class="string">'../static/img/favicon2.ico'</span>) <span class="comment">// 通知图标</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">document</span>.querySelector(<span class="string">'#showNotification'</span>).onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> myNotification  = <span class="keyword">new</span> <span class="built_in">window</span>.Notification(options.title, options)</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 消息可点击</span></span><br><span class="line">    myNotification.onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">'click notification'</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>2. 引入</strong></p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--src/index.html--&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">"showNotification"</span>&gt;</span>弹出消息通知<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"render/notification.js"</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p><code>mac</code>上的消息通知</p>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/76.png" alt></p>
<h2 id="11-2-监听网络变化"><a href="#11-2-监听网络变化" class="headerlink" title="11.2 监听网络变化"></a>11.2 监听网络变化</h2><p><strong>1. 基本使用</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"> <span class="comment">// 监听网络变化</span></span><br><span class="line"><span class="comment">// 端开网络 再次连接测试</span></span><br><span class="line"> <span class="built_in">window</span>.addEventListener(<span class="string">'online'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'online'</span>)</span><br><span class="line"> &#125;); </span><br><span class="line"> </span><br><span class="line"> <span class="built_in">window</span>.addEventListener(<span class="string">'offline'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'offline'</span>)</span><br><span class="line"> &#125;);</span><br></pre></td></tr></table></figure>
<p> <strong>2. 监听网络变化实现消息通知</strong></p>
 <figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 端开网络 再次连接测试</span></span><br><span class="line"><span class="comment">// 监听网络变化实现消息通知</span></span><br><span class="line"> <span class="built_in">window</span>.addEventListener(<span class="string">'online'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'online'</span>)</span><br><span class="line"> &#125;); </span><br><span class="line"> <span class="built_in">window</span>.addEventListener(<span class="string">'offline'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="comment">// 断开网络触发事件</span></span><br><span class="line">    <span class="keyword">var</span> options = &#123;</span><br><span class="line">        title: <span class="string">'QQ邮箱'</span>,</span><br><span class="line">        body: <span class="string">'网络异常，请检查你的网络'</span>,</span><br><span class="line">        icon: path.join(<span class="string">'../static/img/favicon2.ico'</span>) <span class="comment">// 通知图标</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> myNotification  = <span class="keyword">new</span> <span class="built_in">window</span>.Notification(options.title, options)</span><br><span class="line">    myNotification.onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">'click notification'</span>)</span><br><span class="line">    &#125;</span><br><span class="line"> &#125;);</span><br></pre></td></tr></table></figure>
<p> <img src="https://poetries1.gitee.io/img-repo/20191001/77.png" alt></p>
<h1 id="十二、注册全局快捷键-剪切板事件-nativeImage-模块"><a href="#十二、注册全局快捷键-剪切板事件-nativeImage-模块" class="headerlink" title="十二、注册全局快捷键/剪切板事件/nativeImage 模块"></a>十二、注册全局快捷键/剪切板事件/nativeImage 模块</h1><blockquote>
<p><code>Electron</code> 注册全局快捷键 (<code>globalShortcut</code>) 以及 <code>clipboard</code> 剪 切板事件以及 <code>nativeImage</code> 模块(实现类似播放器点击机器码自动复制功 能)</p>
</blockquote>
<h2 id="12-1-注册全局快捷键"><a href="#12-1-注册全局快捷键" class="headerlink" title="12.1 注册全局快捷键"></a>12.1 注册全局快捷键</h2><p><img src="https://poetries1.gitee.io/img-repo/20191001/78.png" alt></p>
<ul>
<li><a href="https://electronjs.org/docs/tutorial/keyboard-shortcuts" target="_blank" rel="noopener">keyboard-shortcuts文档</a></li>
<li><a href="https://electronjs.org/docs/api/app" target="_blank" rel="noopener">app模块参考文档</a></li>
</ul>
<p><strong>1. 新建src/main/shortCut.js</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123;globalShortcut, app&#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>)</span><br><span class="line"></span><br><span class="line">app.on(<span class="string">'ready'</span>, ()=&gt;&#123;</span><br><span class="line">    <span class="comment">// 注册全局快捷键</span></span><br><span class="line">    globalShortcut.register(<span class="string">'command+e'</span>, ()=&gt;&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="number">1</span>)</span><br><span class="line">    &#125;)</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 检测快捷键是否注册成功 true是注册成功</span></span><br><span class="line">    <span class="keyword">let</span> isRegister = globalShortcut.isRegistered(<span class="string">'command+e'</span>)</span><br><span class="line">    <span class="built_in">console</span>.log(isRegister)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 退出的时候取消全局快捷键</span></span><br><span class="line">app.on(<span class="string">'will-quit'</span>, ()=&gt;&#123;</span><br><span class="line">    globalShortcut.unregister(<span class="string">'command+e'</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><strong>2. 引入src/index.js</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 注意在外部引入即可 不用放到app中</span></span><br><span class="line"><span class="built_in">require</span>(<span class="string">'./main/shortCut.js'</span>)</span><br></pre></td></tr></table></figure>
<h2 id="12-2-剪切板clipboard、nativeImage-模块"><a href="#12-2-剪切板clipboard、nativeImage-模块" class="headerlink" title="12.2  剪切板clipboard、nativeImage 模块"></a>12.2  剪切板clipboard、nativeImage 模块</h2><p><img src="https://poetries1.gitee.io/img-repo/20191001/79.png" alt></p>
<ul>
<li><a href="https://electronjs.org/docs/api/clipboard" target="_blank" rel="noopener">剪切板clipboard文档</a></li>
<li><a href="https://electronjs.org/docs/api/native-image" target="_blank" rel="noopener">nativeImage模块</a></li>
</ul>
<p><strong>1. html</strong></p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--src/index.html--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h2</span>&gt;</span>双击下面信息复制<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">p</span> <span class="attr">id</span>=<span class="string">'msg'</span>&gt;</span>123456789<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">"plat"</span>&gt;</span>粘贴<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">input</span> <span class="attr">id</span>=<span class="string">"text"</span> <span class="attr">type</span>=<span class="string">"text"</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span>.</span><br><span class="line"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h2</span>&gt;</span>复制图片到界面<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">"copyImg"</span>&gt;</span>复制图片<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"render/clipboard.js"</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p><strong>2. 新建src/render/clipboard.js</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// clipboard可以在主进程或渲染进程使用</span></span><br><span class="line"><span class="keyword">const</span> &#123; clipboard, nativeImage &#125;  = <span class="built_in">require</span>(<span class="string">'electron'</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">//复制</span></span><br><span class="line"><span class="comment">// 运行ctrl+v可看到复制的内容</span></span><br><span class="line"><span class="comment">// clipboard.writeText('poetries')</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// clipboard.readText() //获取复制的内容 粘贴</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 双击复制消息</span></span><br><span class="line"><span class="keyword">let</span> msg = <span class="built_in">document</span>.querySelector(<span class="string">'#msg'</span>)</span><br><span class="line"><span class="keyword">let</span> plat = <span class="built_in">document</span>.querySelector(<span class="string">'#plat'</span>)</span><br><span class="line"><span class="keyword">let</span> text = <span class="built_in">document</span>.querySelector(<span class="string">'#text'</span>)</span><br><span class="line"></span><br><span class="line">msg.ondblclick  = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    clipboard.writeText(msg.innerHTML)</span><br><span class="line">    alert(msg.innerHTML)</span><br><span class="line">&#125;</span><br><span class="line">plat.onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    text.value = clipboard.readText()</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 复制图片显示到界面</span></span><br><span class="line"><span class="keyword">let</span> copyImg = <span class="built_in">document</span>.querySelector(<span class="string">'#copyImg'</span>)</span><br><span class="line">copyImg.onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 结合nativeImage模块</span></span><br><span class="line">    <span class="keyword">let</span> image = nativeImage.createFromPath(<span class="string">'../static/img/lover.png'</span>) </span><br><span class="line"></span><br><span class="line">    <span class="comment">// 复制图片</span></span><br><span class="line">    clipboard.writeImage(image)</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 粘贴图片</span></span><br><span class="line">    <span class="keyword">let</span> imgSrc = clipboard.readImage().toDataURL() <span class="comment">// base64图片</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 显示到页面上</span></span><br><span class="line">    <span class="keyword">let</span> imgDom = <span class="keyword">new</span> Image()</span><br><span class="line">    imgDom.src = imgSrc </span><br><span class="line">    <span class="built_in">document</span>.body.appendChild(imgDom)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h1 id="十三、结合electron-vue"><a href="#十三、结合electron-vue" class="headerlink" title="十三、结合electron-vue"></a>十三、结合electron-vue</h1><h2 id="13-1-electron-vue-的使用"><a href="#13-1-electron-vue-的使用" class="headerlink" title="13.1 electron-vue 的使用"></a>13.1 electron-vue 的使用</h2><p><strong>1. electron-vue 的一些资源</strong></p>
<blockquote>
<p><a href="https://github.com/SimulatedGREG/electron-vue" target="_blank" rel="noopener">https://github.com/SimulatedGREG/electron-vue</a></p>
</blockquote>
<p><code>Electron-vue</code> 文档 <a href="https://simulatedgreg.gitbooks.io/electron-vue/content/cn" target="_blank" rel="noopener">https://simulatedgreg.gitbooks.io/electron-vue/content/cn</a></p>
<p><strong>2. electron-vue 环境搭建、创建项目</strong></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install -g vue-cli</span><br><span class="line"></span><br><span class="line">vue init simulatedgreg/electron-vue my-project</span><br><span class="line"></span><br><span class="line"><span class="built_in">cd</span> my-project</span><br><span class="line"></span><br><span class="line">yarn <span class="comment"># or npm install</span></span><br><span class="line"></span><br><span class="line">yarn run dev <span class="comment"># or npm run dev</span></span><br></pre></td></tr></table></figure>
<p><strong>3. electron-vue 目录结构分析</strong></p>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/80.png" alt></p>
<h2 id="13-2-electron-vue-中使用-sass-ElementUi"><a href="#13-2-electron-vue-中使用-sass-ElementUi" class="headerlink" title="13.2 electron-vue 中使用 sass/ElementUi"></a>13.2 electron-vue 中使用 sass/ElementUi</h2><p><strong>1. electron-vue UI 框架 ElementUi 的使用</strong></p>
<blockquote>
<p><a href="http://element-cn.eleme.io/#/zh-CN" target="_blank" rel="noopener">http://element-cn.eleme.io/#/zh-CN</a></p>
</blockquote>
<p><strong>2. electron-vue 中使用 sass</strong></p>
<ul>
<li><a href="https://simulatedgreg.gitbooks.io/electron-vue/content/cn/using_pre-processors.html" target="_blank" rel="noopener">electron-vue 中使用 sass</a></li>
</ul>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 安装 sass-loader:</span></span><br><span class="line"></span><br><span class="line">npm install --save-dev sass-loader node-sass</span><br></pre></td></tr></table></figure>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--vue 文件中修改 style 为如下代码:--&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">style</span> <span class="attr">lang</span>=<span class="string">"scss"</span>&gt;</span> </span><br><span class="line">    body &#123;</span><br><span class="line"><span class="css">        <span class="comment">/* SCSS */</span> </span></span><br><span class="line">    &#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h2 id="13-3-electron-vue-中隐藏顶部菜单隐藏"><a href="#13-3-electron-vue-中隐藏顶部菜单隐藏" class="headerlink" title="13.3 electron-vue 中隐藏顶部菜单隐藏"></a>13.3 electron-vue 中隐藏顶部菜单隐藏</h2><blockquote>
<p>electron-vue 中隐藏顶部菜单隐藏顶部最大化、最小化、关闭按钮 自定最大化、最小化 、关闭按钮</p>
</blockquote>
<p><strong>1. electron-vue 中隐藏顶部菜单</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/main/index.js</span></span><br><span class="line">mainWindow.setMenu(<span class="literal">null</span>)</span><br></pre></td></tr></table></figure>
<p><strong>2. electron-vue 中隐藏关闭 最大化 最小化按钮</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// src/main/index.js</span></span><br><span class="line">mainWindow = <span class="keyword">new</span> BrowserWindow(&#123;</span><br><span class="line">    height: <span class="number">620</span>,</span><br><span class="line">    useContentSize: <span class="literal">true</span>,</span><br><span class="line">    width: <span class="number">1280</span>,</span><br><span class="line">    frame: <span class="literal">false</span> <span class="comment">/*去掉顶部导航 去掉关闭按钮 最大化最小化按钮*/</span></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><strong>3 .electron-vue 自定义关闭/最大化最小化按钮</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 注意在mac下不需要监听窗口最大最小化、以为系统默认支持，这个只是针对windows平台</span></span><br><span class="line"></span><br><span class="line">ipc.on(<span class="string">'window-min'</span>,<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    mainWindow.minimize();</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">//登录窗口最大化 </span></span><br><span class="line">ipc.on(<span class="string">'window-max'</span>,<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (mainWindow.isMaximized()) &#123;</span><br><span class="line">        mainWindow.restore();</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        mainWindow.maximize();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;) </span><br><span class="line"></span><br><span class="line">ipc.on(<span class="string">'window-close'</span>,<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    mainWindow.close();</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><strong>4. electron-vue 自定义导航可拖拽</strong></p>
<ul>
<li>可拖拽的 <code>css</code>: <code>-webkit-app-region: drag;</code></li>
<li>不可拖拽的 <code>css</code>:  <code>-webkit-app-region: no-drag;</code></li>
</ul>
<h2 id="13-4-使用electron-vue开发舆情监控系统"><a href="#13-4-使用electron-vue开发舆情监控系统" class="headerlink" title="13.4 使用electron-vue开发舆情监控系统"></a>13.4 使用electron-vue开发舆情监控系统</h2><h3 id="13-4-1-配置开发环境"><a href="#13-4-1-配置开发环境" class="headerlink" title="13.4.1 配置开发环境"></a>13.4.1 配置开发环境</h3><p><strong>1. 项目搭建</strong></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install -g vue-cli</span><br><span class="line"></span><br><span class="line">vue init simulatedgreg/electron-vue my-project</span><br><span class="line"></span><br><span class="line"><span class="built_in">cd</span> my-project</span><br><span class="line"></span><br><span class="line">yarn <span class="comment"># or npm install</span></span><br><span class="line"></span><br><span class="line">yarn run dev <span class="comment"># or npm run dev</span></span><br></pre></td></tr></table></figure>
<p><strong>2. 安装一些依赖</strong></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 安装 sass-loader:</span></span><br><span class="line">npm install --save-dev sass-loader node-sass</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装elementUI、js-md5</span></span><br><span class="line">npm i element-ui  js-md5 -S</span><br></pre></td></tr></table></figure>
<ul>
<li>在<code>.electron-vue/webpack.renderer.config.js</code>中配置<code>sass-loader</code>就可以编写<code></code>sass`了</li>
</ul>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--vue 文件中修改 style 为如下代码:--&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">style</span> <span class="attr">lang</span>=<span class="string">"scss"</span>&gt;</span> </span><br><span class="line">    body &#123;</span><br><span class="line"><span class="css">        <span class="comment">/* SCSS */</span> </span></span><br><span class="line">    &#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h3 id="13-4-2-主进程配置"><a href="#13-4-2-主进程配置" class="headerlink" title="13.4.2 主进程配置"></a>13.4.2 主进程配置</h3><p><strong>1. <code>src/main/index.js</code></strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">createWindow</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 去掉顶部菜单</span></span><br><span class="line">  mainWindow.setMenu(<span class="literal">null</span>)</span><br><span class="line">  </span><br><span class="line">  <span class="comment">// 菜单项</span></span><br><span class="line">  <span class="built_in">require</span>(<span class="string">'./model/menu.js'</span>);</span><br><span class="line">  </span><br><span class="line">  <span class="comment">// 系统托盘相关</span></span><br><span class="line">  <span class="built_in">require</span>(<span class="string">'./model/tray.js'</span>);</span><br></pre></td></tr></table></figure>
<p><strong>2. <code>src/main/menu.js</code>菜单配置</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123; Menu,ipcMain,BrowserWindow&#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//右键菜单</span></span><br><span class="line"><span class="keyword">const</span> contextMenuTemplate=[</span><br><span class="line">    &#123;</span><br><span class="line">        label: <span class="string">'复制'</span>, <span class="attr">role</span>: <span class="string">'copy'</span> &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">        label: <span class="string">'黏贴'</span>, <span class="attr">role</span>: <span class="string">'paste'</span> &#125;,        </span><br><span class="line">    &#123; <span class="attr">type</span>: <span class="string">'separator'</span> &#125;, <span class="comment">//分隔线</span></span><br><span class="line">    &#123;</span><br><span class="line">        label: <span class="string">'其他功能'</span>,     </span><br><span class="line">        click: <span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">'click'</span>)</span><br><span class="line">         &#125;</span><br><span class="line">    &#125;</span><br><span class="line">];</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> contextMenu=Menu.buildFromTemplate(contextMenuTemplate);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">ipcMain.on(<span class="string">'contextmenu'</span>,<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line"></span><br><span class="line">    contextMenu.popup(BrowserWindow.getFocusedWindow());</span><br><span class="line"></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p><strong>3. <code>src/main/tray.js</code>系统托盘配置</strong></p>
<blockquote>
<p>托盘点击监听事件只有在<code>windows</code>下才生效，<code>mac</code>系统默认支持</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">const</span> path=<span class="built_in">require</span>(<span class="string">'path'</span>);</span><br><span class="line">    <span class="keyword">const</span> &#123;app,Menu,BrowserWindow,Tray, shell&#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//创建系统托盘</span></span><br><span class="line">    <span class="keyword">const</span> tray = <span class="keyword">new</span> Tray(path.resolve(__static, <span class="string">'favicon.png'</span>))</span><br><span class="line"></span><br><span class="line">    <span class="comment">//给托盘增加右键菜单</span></span><br><span class="line">    <span class="keyword">const</span> template= [</span><br><span class="line">        &#123;</span><br><span class="line">            label: <span class="string">'设置'</span>,</span><br><span class="line">            click: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">                shell.openExternal(<span class="string">'http://blog.poetries.top'</span>)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">            label: <span class="string">'帮助'</span>,</span><br><span class="line">            click: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">                shell.openExternal(<span class="string">'http://blog.poetries.top/2019/01/06/electron-summary'</span>)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">            label: <span class="string">'关于'</span>,</span><br><span class="line">            click: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">                shell.openExternal(<span class="string">'https://github.com/poetries/yuqing-monitor-electron'</span>)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">            label: <span class="string">'退出'</span>,</span><br><span class="line">            click: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">                <span class="comment">// BrowserWindow.getFocusedWindow().webContents().send('close-main-window');</span></span><br><span class="line">                app.quit();</span><br><span class="line">            </span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    ];</span><br><span class="line"></span><br><span class="line">    <span class="keyword">const</span> menu = Menu.buildFromTemplate(template);</span><br><span class="line">    tray.setContextMenu(menu);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    tray.setToolTip(<span class="string">'舆情监控系统'</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">//监听关闭事件隐藏到系统托盘</span></span><br><span class="line">    <span class="comment">// 这里需要注意：在window中才生效，mac下系统默认支持</span></span><br><span class="line">    <span class="comment">// var win = BrowserWindow.getFocusedWindow();</span></span><br><span class="line">    <span class="comment">// win.on('close',(e)=&gt;&#123;</span></span><br><span class="line">    <span class="comment">//         if(!win.isFocused())&#123;</span></span><br><span class="line">    <span class="comment">//             win=null;</span></span><br><span class="line">    <span class="comment">//         &#125;else&#123;</span></span><br><span class="line">    <span class="comment">//             e.preventDefault();  /*阻止应用退出*/</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">//             win.hide(); /*隐藏当前窗口*/</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">//         &#125;       </span></span><br><span class="line">    <span class="comment">// &#125;)</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">// //监听托盘的双击事件</span></span><br><span class="line">    <span class="comment">// tray.on('double-click',()=&gt;&#123;               </span></span><br><span class="line">    <span class="comment">//     win.show();</span></span><br><span class="line">    <span class="comment">// &#125;)</span></span><br><span class="line">&#125;)()</span><br></pre></td></tr></table></figure>
<p><strong>4. <code>src/main/shortCut.js</code>快捷键配置</strong></p>
<p>在<code>src/main/index.js</code>中引入（<code>require(&#39;src/main/shortCut.js&#39;)</code>）即可，不需要放到<code>app</code>监控中</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> &#123;globalShortcut, app&#125; = <span class="built_in">require</span>(<span class="string">'electron'</span>)</span><br><span class="line"></span><br><span class="line">app.on(<span class="string">'ready'</span>, ()=&gt;&#123;</span><br><span class="line">    <span class="comment">// 注册全局快捷键</span></span><br><span class="line">    globalShortcut.register(<span class="string">'command+e'</span>, ()=&gt;&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="number">1</span>)</span><br><span class="line">    &#125;)</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 检测快捷键是否注册成功 true是注册成功</span></span><br><span class="line">    <span class="keyword">let</span> isRegister = globalShortcut.isRegistered(<span class="string">'command+e'</span>)</span><br><span class="line">    <span class="built_in">console</span>.log(isRegister)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 退出的时候取消全局快捷键</span></span><br><span class="line">app.on(<span class="string">'will-quit'</span>, ()=&gt;&#123;</span><br><span class="line">    globalShortcut.unregister(<span class="string">'command+e'</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h3 id="13-4-3-渲染进程配置"><a href="#13-4-3-渲染进程配置" class="headerlink" title="13.4.3 渲染进程配置"></a>13.4.3 渲染进程配置</h3><p><strong>1. src/render/main.js配置</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> Vue <span class="keyword">from</span> <span class="string">'vue'</span></span><br><span class="line"><span class="keyword">import</span> axios <span class="keyword">from</span> <span class="string">'axios'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> App <span class="keyword">from</span> <span class="string">'./App'</span></span><br><span class="line"><span class="keyword">import</span> router <span class="keyword">from</span> <span class="string">'./router'</span></span><br><span class="line"><span class="keyword">import</span> store <span class="keyword">from</span> <span class="string">'./store'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> ElementUI <span class="keyword">from</span> <span class="string">'element-ui'</span>;</span><br><span class="line"><span class="keyword">import</span> <span class="string">'element-ui/lib/theme-chalk/index.css'</span>;</span><br><span class="line"><span class="keyword">import</span> VueHighcharts <span class="keyword">from</span> <span class="string">'vue-highcharts'</span>;</span><br><span class="line"><span class="keyword">import</span> VueSocketIO <span class="keyword">from</span> <span class="string">'vue-socket.io'</span></span><br><span class="line"></span><br><span class="line">Vue.use(ElementUI);</span><br><span class="line">Vue.use(VueHighcharts);</span><br><span class="line"></span><br><span class="line"><span class="comment">//引入socket.io配置连接</span></span><br><span class="line">Vue.use(<span class="keyword">new</span> VueSocketIO(&#123;</span><br><span class="line">  debug: <span class="literal">true</span>,</span><br><span class="line">  connection: <span class="string">'http://118.123.14.36:3000'</span>,</span><br><span class="line">  vuex: &#123;</span><br><span class="line">      store,</span><br><span class="line">      actionPrefix: <span class="string">'SOCKET_'</span>,</span><br><span class="line">      mutationPrefix: <span class="string">'SOCKET_'</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;))</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (!process.env.IS_WEB) Vue.use(<span class="built_in">require</span>(<span class="string">'vue-electron'</span>))</span><br><span class="line">Vue.http = Vue.prototype.$http = axios</span><br><span class="line">Vue.config.productionTip = <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/* eslint-disable no-new */</span></span><br><span class="line"><span class="keyword">new</span> Vue(&#123;</span><br><span class="line">  components: &#123; App &#125;,</span><br><span class="line">  router,</span><br><span class="line">  store,</span><br><span class="line">  template: <span class="string">'&lt;App/&gt;'</span></span><br><span class="line">&#125;).$mount(<span class="string">'#app'</span>)</span><br></pre></td></tr></table></figure>
<p><strong>2. 路由配置src/renderer/router/index.js</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> Vue <span class="keyword">from</span> <span class="string">'vue'</span></span><br><span class="line"><span class="keyword">import</span> Router <span class="keyword">from</span> <span class="string">'vue-router'</span></span><br><span class="line"></span><br><span class="line">Vue.use(Router)</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">new</span> Router(&#123;</span><br><span class="line">  routes: [</span><br><span class="line">    &#123;</span><br><span class="line">      path: <span class="string">'/home'</span>,</span><br><span class="line">      name: <span class="string">'home'</span>,</span><br><span class="line">      component: <span class="built_in">require</span>(<span class="string">'@/components/Home'</span>).default</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      path: <span class="string">'/report'</span>,</span><br><span class="line">      name: <span class="string">'report'</span>,</span><br><span class="line">      component: <span class="built_in">require</span>(<span class="string">'@/components/Report'</span>).default</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      path: <span class="string">'/negativereport'</span>,</span><br><span class="line">      name: <span class="string">'negativereport'</span>,</span><br><span class="line">      component: <span class="built_in">require</span>(<span class="string">'@/components/NegativeReport'</span>).default</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      path: <span class="string">'/positivereport'</span>,</span><br><span class="line">      name: <span class="string">'positivereport'</span>,</span><br><span class="line">      component: <span class="built_in">require</span>(<span class="string">'@/components/PositiveReport'</span>).default</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      path: <span class="string">'/keyword'</span>,</span><br><span class="line">      name: <span class="string">'keyword'</span>,</span><br><span class="line">      component: <span class="built_in">require</span>(<span class="string">'@/components/KeyWord'</span>).default</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      path: <span class="string">'/alarm'</span>,</span><br><span class="line">      name: <span class="string">'alarm'</span>,</span><br><span class="line">      component: <span class="built_in">require</span>(<span class="string">'@/components/Alarm'</span>).default</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      path: <span class="string">'/msg'</span>,</span><br><span class="line">      name: <span class="string">'msg'</span>,</span><br><span class="line">      component: <span class="built_in">require</span>(<span class="string">'@/components/Msg'</span>).default</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      path: <span class="string">'*'</span>,</span><br><span class="line">      redirect: <span class="string">'/home'</span></span><br><span class="line">    &#125;</span><br><span class="line">  ]</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<blockquote>
<p><a href="https://github.com/poetries/yuqing-monitor-electron/tree/master/src/renderer" target="_blank" rel="noopener">其他页面更多详情Github</a></p>
</blockquote>
<p><strong>3. 在渲染进程中使用主进程方式</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// electron挂载到了vue实例上 $electron</span></span><br><span class="line"><span class="keyword">this</span>.$electron.shell</span><br></pre></td></tr></table></figure>
<h3 id="13-4-4-多平台打包"><a href="#13-4-4-多平台打包" class="headerlink" title="13.4.4 多平台打包"></a>13.4.4 多平台打包</h3><blockquote>
<p>需要注意的是打包<code>mac</code>版本在<code>mac</code>系统上打包，打包<code>window</code>则在<code>windows</code>上打包，可以避免很多问题</p>
</blockquote>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 在不同平台上执行即可打包应用</span></span><br><span class="line">npm run build</span><br></pre></td></tr></table></figure>
<h4 id="13-4-4-1-打包介绍"><a href="#13-4-4-1-打包介绍" class="headerlink" title="13.4.4.1 打包介绍"></a>13.4.4.1 打包介绍</h4><blockquote>
<p><a href="https://simulatedgreg.gitbooks.io/electron-vue/content/cn/using-electron-packager.html" target="_blank" rel="noopener">electron-vue打包文档</a></p>
</blockquote>
<p><strong>1. electron 中构建应用最常用的模块</strong></p>
<ul>
<li><code>electron-packager</code> </li>
<li><code>electron-builder</code></li>
</ul>
<blockquote>
<p><code>electron-packager</code> 和 <code>electron-builder</code>在自己单独创建的应用用也可以完成打包功 能。但是由于配置太复杂所以我们不建议单独配置</p>
</blockquote>
<p><strong>2. electron-forge</strong></p>
<blockquote>
<p><a href="https://github.com/electron-userland/electron-forge" target="_blank" rel="noopener">https://github.com/electron-userland/electron-forge</a></p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">electron-forge package </span><br><span class="line">electron-forge make</span><br></pre></td></tr></table></figure>
<p><strong>3. electron-vue中的打包方式</strong></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># https://simulatedgreg.gitbooks.io/electron-vue/content/cn/using-electron-packager. html</span></span><br><span class="line"><span class="comment"># 之需要执行一条命令</span></span><br><span class="line">npm run build</span><br></pre></td></tr></table></figure>
<h4 id="13-4-4-2-修改应用信息"><a href="#13-4-4-2-修改应用信息" class="headerlink" title="13.4.4.2 修改应用信息"></a>13.4.4.2 修改应用信息</h4><p><strong>1. 修改package.json</strong></p>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/81.png" alt></p>
<p><strong>2. 修改src/index.ejs标题信息</strong></p>
<p><strong>3. 修改build/icons图标</strong></p>
<h4 id="13-4-4-3-打包遇到的问题"><a href="#13-4-4-3-打包遇到的问题" class="headerlink" title="13.4.4.3 打包遇到的问题"></a>13.4.4.3 打包遇到的问题</h4><p><strong>1. 创建应用托盘的时候可能会遇到错误</strong></p>
<ul>
<li>把托盘图片放在根目录<code>static</code>里面，然后注意下面写法。 </li>
</ul>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> tray = <span class="keyword">new</span> Tray(path.join(__static,<span class="string">'favicon.ico'</span>))</span><br></pre></td></tr></table></figure>
<ul>
<li>如果托盘路径没有问题，还是包托盘相关错误的话，把托盘对应的图片换成<code>.png</code> 格式重试</li>
</ul>
<p><strong>2. 模块问题可能会遇到的错误</strong></p>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/82.png" alt></p>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/83.png" alt></p>
<p><strong>解决办法</strong></p>
<ul>
<li>删掉 <code>node_modules</code> 然后重新用 <code>npm install</code> 安装依赖</li>
<li>用 <code>yarn</code> 来安装模块</li>
<li>用手机创建一个热点电脑连上热点重试</li>
</ul>
<blockquote>
<p>最后执行<code>yarn run build</code>即可</p>
</blockquote>
<p><img src="https://poetries1.gitee.io/img-repo/20191001/84.png" alt></p>
<blockquote>
<p>项目源码 <a href="https://github.com/poetries/yuqing-monitor-electron" target="_blank" rel="noopener">https://github.com/poetries/yuqing-monitor-electron</a></p>
</blockquote>
<h1 id="十四、更多参考"><a href="#十四、更多参考" class="headerlink" title="十四、更多参考"></a>十四、更多参考</h1><ul>
<li><a href="https://github.com/poetries/electron-demo" target="_blank" rel="noopener">本文对应DEMO地址</a></li>
<li><a href="https://github.com/electron/electron-api-demos" target="_blank" rel="noopener">一些比较常用的API，克隆后跑起来你就可以快速查看这些常用API</a></li>
<li><a href="https://github.com/poetries/electron-wiki" target="_blank" rel="noopener">electron学习资料整理</a></li>
<li><a href="https://wizardforcel.gitbooks.io/electron-doc/content/faq/electron-faq.html" target="_blank" rel="noopener">electron中文文档</a></li>
</ul>

      </div>
    
  </div>

</article>

<button class="assist-btn2 circle" id="assist_btn2" title="点亮屏幕" style="left: 27px; top: 152px;">
  <i class="iconfont" style="display:inline-block;color:red;width:20px;height:20px;">&#xe61d;</i>
</button>
<button class="assist-btn1 circle" id="assist_btn1" title="关闭屏幕亮度" style="left: 27px; top: 152px;">
  <i class="iconfont toc-title" style="display:inline-block;color:red;width:20px;height:20px;">&#xe61d;</i>
</button>


<script src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>	

<script src="https://my.openwrite.cn/js/readmore.js" type="text/javascript"></script>
<script>
  const btw = new BTWPlugin();
  btw.init({
    id: "container",
    blogId: "22699-1592137983091-414",
    name: "前端进阶之旅",
    qrcode: "https://poetries1.gitee.io/img-repo/2020/06/qrcode.jpg",
    keyword: "3a3b3c",
  });
</script>

<script type="text/javascript">

// white theme
var body = {color: "#555", background: "#000"};
var a_tag = {color: "#222"};
var header = { background: "#222"};
var logo_line_i = {background: "#222"};
// var post_code = {background: "#eee", color: "#222"};

function switch_theme() {
 $("body").css(body);
 $("a:not('.links-of-author-item a, .site-state-item a, .site-state-posts a, .feed-link a, .motion-element a, .post-tags a, .show-commit-cls a, #donate_board a')").css(a_tag);
 $(".header, .footer").css(header);
 $(".logo-line-before i, .logo-line-after i").css(logo_line_i);
 //$(".post code").css(post_code);
 $("#idhyt-surprise-ball #idhyt-surprise-ball-animation .drag").css(a_tag);
 $(".post-title-link, .posts-expand .post-meta, .post-comments-count, .disqus-comment-count, .post-category a, .post-nav-next a, .post-nav-item a").css(a_tag);
 
 // $("code").css({color: '#c5c8c6', background: '#1d1f21'});
 //$("#assist_btn1").hide(1500);
}

$(function () {
$("#assist_btn2").css("display","none");
 $("#assist_btn1").click(function() {
     switch_theme();
$("div#toc.toc-article").css({
 "background":"#eaeaea",
 "opacity":1
});
$(".toc-article ol").show();
$("#toc.toc-article .toc-title").css("color","#a98602");
$("#assist_btn1").css("display","none");
$("#assist_btn2").css("display","block");
 });
$("#assist_btn2").click(function() {
$("#assist_btn2").css("display","none");
$("#assist_btn1").css("display","block");
$("body").css("background","url(http://www.miaov.com/static/ie/images/news/bg.png)")
     $(".header, .footer").css("background","url(http://www.miaov.com/static/ie/images/news/bg.png)")
$(".toc-article ol").toggle(1000);
 });
});


//背景随机

var Y, O, E, L, B, C, T, z, N, S, A, I;
!function() {
var e = function() {
for (O.clearRect(0, 0, L, B), T = [{
x: 0,
y: .7 * B + C
}, {
x: 0,
y: .7 * B - C
}]; T[1].x < L + C;) t(T[0], T[1])
}, t = function(e, t) {
O.beginPath(), O.moveTo(e.x, e.y), O.lineTo(t.x, t.y);
var n = t.x + (2 * I() - .25) * C,
 r = a(t.y);
O.lineTo(n, r), O.closePath(), N -= S / -50, O.fillStyle = "#" + (127 * A(N) + 128 << 16 | 127 * A(N + S / 3) + 128 << 8 | 127 * A(N + S / 3 * 2) + 128).toString(16), O.fill(), T[0] = T[1], T[1] = {
 x: n,
 y: r
}
}, a = function n(e) {
var t = e + (2 * I() - 1.1) * C;
return t > B || t < 0 ? n(e) : t
};
Y = document.getElementById("evanyou"), O = Y.getContext("2d"), E = window.devicePixelRatio || 1, L = window.innerWidth, B = window.innerHeight, C = 90, z = Math, N = 0, S = 2 * z.PI, A = z.cos, I = z.random, Y.width = L * E, Y.height = B * E, O.scale(E, E), O.globalAlpha = .6, document.onclick = e, document.ontouchstart = e, e()
}()

   
$("#toc-eye").click(function(){
$("#toc.toc-article").toggle(1000);
});

</script>


   
  <div class="text-center donation">
    <div class="inner-donation">
      <span class="btn-donation">支持一下</span>
      <div class="donation-body">
        <div class="tip text-center">扫一扫，支持poetries</div>
        <ul>
        
          <li class="item">
            
              <span>微信扫一扫</span>
            
            <img src="/images/weixin.jpg" alt="">
          </li>
        
          <li class="item">
            
              <span>支付宝扫一扫</span>
            
            <img src="/images/zhifubao.jpg" alt="">
          </li>
        
        </ul>
      </div>
    </div>
  </div>


   
  <div class="box-prev-next clearfix">
    <a class="show pull-left" href="/2019/01/02/browser-cache/">
        <i class="icon icon-angle-left"></i>
    </a>
    <a class="show pull-right" href="/2019/01/09/angular7-intro-summary/">
        <i class="icon icon-angle-right"></i>
    </a>
  </div>




</div>


  <a id="backTop" class="back-top">
    <i class="icon-angle-up"></i>
  </a>




  <div class="modal" id="modal">
  <span id="cover" class="cover hide"></span>
  <div id="modal-dialog" class="modal-dialog hide-dialog">
    <div class="modal-header">
      <span id="close" class="btn-close">关闭</span>
    </div>
    <hr>
    <div class="modal-body">
      <ul class="list-toolbox">
        
          <li class="item-toolbox">
            <a
              class="CIRCLE"
              href="/archives/"
              rel="noopener noreferrer"
              target="_self"
              >
              博客
            </a>
          </li>
        
          <li class="item-toolbox">
            <a
              class="CIRCLE"
              href="/categories/"
              rel="noopener noreferrer"
              target="_self"
              >
              分类
            </a>
          </li>
        
          <li class="item-toolbox">
            <a
              class="CIRCLE"
              href="/tags/"
              rel="noopener noreferrer"
              target="_self"
              >
              标签
            </a>
          </li>
        
          <li class="item-toolbox">
            <a
              class="CIRCLE"
              href="/search/"
              rel="noopener noreferrer"
              target="_self"
              >
              搜索
            </a>
          </li>
        
          <li class="item-toolbox">
            <a
              class="CIRCLE"
              href="/link/"
              rel="noopener noreferrer"
              target="_self"
              >
              友链
            </a>
          </li>
        
          <li class="item-toolbox">
            <a
              class="CIRCLE"
              href="/about/"
              rel="noopener noreferrer"
              target="_self"
              >
              关于
            </a>
          </li>
        
      </ul>

    </div>
  </div>
</div>



  
      <div class="fexo-comments comments-post">
    

    

    
    

    

    
    

    

<!-- Gitalk评论插件通用代码 -->
<div id="gitalk-container"></div>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.css">
<script src="https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.min.js"></script>
<script>
const gitalk = new Gitalk({
  clientID: '5567a2c4abb858009d96',
  clientSecret: 'b9039ec056cf5c2346b3cdb63308a28c163f91e5',
  repo: 'poetries.github.io',
  owner: 'poetries',
  // 在这里设置一下截取前50个字符串, 这是因为 github 对 label 的长度有了要求, 如果超过
  // 50个字符串则会报错.
  // id: location.pathname.split('/').pop().substring(0, 49),
  id: location.pathname,
  admin: ['poetries'],
  // facebook-like distraction free mode
  distractionFreeMode: false
})
gitalk.render('gitalk-container')
</script>
<!-- Gitalk代码结束 -->



  </div>

  

  <script type="text/javascript">
  function loadScript(url, callback) {
    var script = document.createElement('script')
    script.type = 'text/javascript';

    if (script.readyState) { //IE
      script.onreadystatechange = function() {
        if (script.readyState == 'loaded' ||
          script.readyState == 'complete') {
          script.onreadystatechange = null;
          callback();
        }
      };
    } else { //Others
      script.onload = function() {
        callback();
      };
    }

    script.src = url;
    document.getElementsByTagName('head')[0].appendChild(script);
  }

  window.onload = function() {
    loadScript('/js/bundle.js?235683', function() {
      // load success
    });
  }
</script>


  <!-- 页面点击小红心 -->
  <script type="text/javascript" src="/js/clicklove.js"></script>
 
  
</body>
</html>
